﻿///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2023, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

// Форма параметризуется:
//
//      Заголовок     - Строка  - заголовок формы.
//      ЗначенияПолей - Строка  - сериализованное значение контактной информации или пустая строка для 
//                                ввода нового.
//      Представление - Строка  - представление адреса (используется только при работе со старыми данными).
//      ВидКонтактнойИнформации - СправочникСсылка.ВидыКонтактнойИнформации, Структура - описание того, что мы
//                                редактируем.
//      Комментарий  - Строка   - необязательный комментарий, для подстановки в поле "Комментарий".
//
//      ВозвращатьСписокЗначений - Булево - необязательный флаг того, что возвращаемое значение поля.
//                                 КонтактнаяИнформация будет иметь тип СписокЗначений (совместимость).
//
//  Результат выбора:
//      Структура - поля:
//          * КонтактнаяИнформация   - Строка - XML контактной информации.
//          * Представление          - Строка - Представление.
//          * Комментарий            - Строка - Комментарий.
//          * ВведеноВСвободнойФорме - Булево - флаг ввода.
//

#Область ОбработчикиСобытийФормы

&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
	
	Если Не Параметры.Свойство("ОткрытаПоСценарию") Тогда
		ВызватьИсключение НСтр("ru = 'Обработка не предназначена для непосредственного использования.'");
	КонецЕсли;
	
	// Настройки формы
	СведенияОАдресномКлассификаторе = УправлениеКонтактнойИнформациейСлужебныйПовтИсп.СведенияОДоступностиАдресногоКлассификатора();
	ЕстьЗагруженныйКлассификатор      = СведенияОАдресномКлассификаторе.Получить("ИспользоватьЗагруженные");
	ВебКлассификаторДоступен          = СведенияОАдресномКлассификаторе.Получить("КлассификаторДоступен");
	ИспользуетсяАдресныйКлассификатор = СведенияОАдресномКлассификаторе.Получить("ИспользуетсяАдресныйКлассификатор");
	ВебСервисИспользуется           = ВебКлассификаторДоступен;
	
	Если Не ИспользуетсяАдресныйКлассификатор Тогда
		ОтключитьВозможностьВыбораАдресныхСведенийИзКлассификатора();
	КонецЕсли;
	
	ЕстьПравоЗагружатьКлассификатор = Обработки.РасширенныйВводКонтактнойИнформации.ЕстьВозможностьИзмененияАдресногоКлассификатора();
	
	Параметры.Свойство("ВозвращатьСписокЗначений", ВозвращатьСписокЗначений);
	
	ОсновнаяСтрана           = РаботаСАдресамиКлиентСервер.ОсновнаяСтрана();
	ВидКИ = УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации(Параметры.ВидКонтактнойИнформации);
	ВидКонтактнойИнформации = ВидКИ;
	ПриСозданииНаСервереХранитьИсториюИзменений();
	
	Заголовок = ?(ПустаяСтрока(Параметры.Заголовок), Строка(ВидКИ.Ссылка), Параметры.Заголовок);
	
	СкрыватьНеактуальныеАдреса  = ВидКонтактнойИнформации.СкрыватьНеактуальныеАдреса;
	ТолькоНациональныйАдрес     = ВидКонтактнойИнформации.ТолькоНациональныйАдрес;
	ТипКонтактнойИнформации     = ВидКонтактнойИнформации.Тип;
	МеждународныйФорматАдреса   = ВидКонтактнойИнформации.МеждународныйФорматАдреса;
	
	Элементы.АдресВСвободнойФорме.Видимость                                         = Не ВидКонтактнойИнформации.ПроверятьКорректность;
	Элементы.ПредставлениеАдресаКонтекстноеМенюВвестиАдресВСвободнойФорме.Видимость = Не ВидКонтактнойИнформации.ПроверятьКорректность;
	
	// Пытаемся заполнить из параметров.
	ЗначенияПолей = ОпределитьЗначениеАдреса(Параметры);
	
	Если ПустаяСтрока(ЗначенияПолей) Тогда
		НаселенныйПунктДетально = УправлениеКонтактнойИнформацией.ОписаниеНовойКонтактнойИнформации(Перечисления.ТипыКонтактнойИнформации.Адрес); // Новый адрес
		НаселенныйПунктДетально.AddressType = РаботаСАдресамиКлиентСервер.МуниципальныйАдрес();
	ИначеЕсли УправлениеКонтактнойИнформациейКлиентСервер.ЭтоКонтактнаяИнформацияВJSON(ЗначенияПолей) Тогда
		ДанныеАдреса = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(ЗначенияПолей, Перечисления.ТипыКонтактнойИнформации.Адрес);
		НаселенныйПунктДетально = РаботаСАдресами.ПодготовитьАдресДляВвода(ДанныеАдреса);
	Иначе
		XDTOКонтактная = ИзвлечьСтарыйФорматАдреса(ЗначенияПолей, ТипКонтактнойИнформации);
		ДанныеАдреса = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияВСтруктуруJSON(XDTOКонтактная, ТипКонтактнойИнформации);
		НаселенныйПунктДетально = РаботаСАдресами.ПодготовитьАдресДляВвода(ДанныеАдреса);
	КонецЕсли;
	
	Если МеждународныйФорматАдреса И Не УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType) Тогда
		НаселенныйПунктДетально.AddressType = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес();
	ИначеЕсли ЗначениеЗаполнено(Параметры.ТипАдреса) Тогда
		УстановитьТипАдресаИзПараметра(Параметры.ТипАдреса);
	КонецЕсли;
	
	ЗаполнениеПолейАдресаДляРанееВведенныхАдресов();
	ЗаполнитьПредопределенныеВариантыАдреса(Параметры);
	
	УстановитьЗначениеРеквизитовПоКонтактнойИнформации(НаселенныйПунктДетально);
	
	Если ЗначениеЗаполнено(НаселенныйПунктДетально.Comment) Тогда
		Элементы.ОсновныеСтраницы.ОтображениеСтраниц = ОтображениеСтраницФормы.ЗакладкиСверху;
		Элементы.СтраницаКомментарий.Картинка = ОбщегоНазначенияКлиентСервер.КартинкаКомментария(Комментарий);
	Иначе
		Элементы.ОсновныеСтраницы.ОтображениеСтраниц = ОтображениеСтраницФормы.Нет;
	КонецЕсли;
	
	Если ТолькоНациональныйАдрес Тогда
		
		Элементы.Страна.Видимость = Ложь;
		Элементы.ОКТМО.Видимость  = ВидКонтактнойИнформации.УказыватьОКТМО;
		
		Если Страна <> ОсновнаяСтрана Тогда
			ОсновнаяСтранаНаименование = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОсновнаяСтрана, "Наименование");
			// Считаем адрес российским
			ТекстПредупрежденияПриОткрытии = НСтр("ru = 'Адрес введен некорректно: допускается ввод только национальных адресов.
			|Значение поля ""Страна"" было изменено на %1, проверьте остальные поля.'");
			ТекстПредупрежденияПриОткрытии = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(ТекстПредупрежденияПриОткрытии, ОсновнаяСтранаНаименование);
			ПолеПредупрежденияПриОткрытии               = "СтранаВСвободнойФорме";
			Модифицированность                          = Истина;
			Элементы.Страна.Доступность                 = Ложь;
			Элементы.Страна.Видимость                   = Истина;
			Элементы.СтранаВСвободнойФорме.Видимость    = Истина;
			Элементы.СтранаВСвободнойФорме.КнопкаВыбора = Ложь;
			Элементы.СтранаВСвободнойФорме.Доступность  = Ложь;
		
		КонецЕсли;
		
		Если СтрНачинаетсяС(ВРег(НаселенныйПунктДетально.value), ВРег(НаселенныйПунктДетально.country) + ",") Тогда
			ЧастиАдреса                   = СтрРазделить(НаселенныйПунктДетально.value, ",");
			ЧастиАдреса.Удалить(0);
			НаселенныйПунктДетально.value = СокрЛП(СтрСоединить(ЧастиАдреса, ","));
			ПредставлениеАдреса           = НаселенныйПунктДетально.value;
		КонецЕсли;
		
		Страна                          = ОсновнаяСтрана;
		
	ИначеЕсли МеждународныйФорматАдреса Тогда
		
		Элементы.ПроверитьЗаполнениеАдреса.Видимость             = Ложь;
		Элементы.АдресныйКлассификаторУстарел.Видимость          = Ложь;
		Элементы.МуниципальноеДеление.Видимость                  = Ложь;
		Элементы.АдминистративноТерриториальноеДеление.Видимость = Ложь;
		Элементы.ЗаполнитьПоПочтовомуИндексу.Видимость           = Ложь;
		Элементы.ЗагрузитьКлассификатор.Видимость                = Ложь;
		Элементы.ГруппаИнформация.Видимость                      = Ложь;
		Элементы.НужнаПомощь.Видимость                           = Ложь;
		Элементы.СтраницаТипАдреса.ТекущаяСтраница               = Элементы.СтраницаДругойАдрес;
		
	КонецЕсли;
	НаселенныйПунктДетально.Country = НаименованиеСтраны(Страна, МеждународныйФорматАдреса);
	
	Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
		Элементы.ГруппаИнформационныеСообщения.Видимость    = Ложь;
		Элементы.НаселенныйПункт.МногострочныйРежим         = Истина;
		Элементы.ФормаКомандаОК.Отображение                 = ОтображениеКнопки.Картинка;
		Элементы.ТипДома.ОтображениеКнопкиВыбора            = ОтображениеКнопкиВыбора.Авто;
		Элементы.ТипСтроения.ОтображениеКнопкиВыбора        = ОтображениеКнопкиВыбора.Авто;
		элементы.ФормаОтмена.Видимость = Ложь;
	КонецЕсли;
	
	ОпределитьОтображениеЭлементовНаФорме(Параметры.ТолькоПросмотр);
	
	Если Не ЕстьПравоЗагружатьКлассификатор И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		Элементы.ИнформацияОЗагрузкеАдресныеСведений.Заголовок = НСтр("ru = 'Для автоподбора и проверки адресов обратитесь к администратору для загрузки адресных сведений.'");
		Элементы.ЗагрузитьКлассификатор.Видимость = Ложь;
	КонецЕсли;
	
	УстановитьКлючИспользованияФормы();
	СформироватьМенюДобавленияСтроенийИПомещений();
	
	СформироватьТекстНужнаПомощь();
	
КонецПроцедуры

&НаКлиенте
Процедура ПриОткрытии(Отказ)
	
	Если ЗначениеЗаполнено(ТекстПредупрежденияПриОткрытии) Тогда
		ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстПредупрежденияПриОткрытии,, ПолеПредупрежденияПриОткрытии);
	КонецЕсли;
	
	ОтобразитьПоляПоТипуАдреса();
	ОбновитьМенюДобавленияСтроенийИПомещений();
	ПоказатьПодсказкуПоТипАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
	
	Оповещение = Новый ОписаниеОповещения("ПодтвердитьИЗакрыть", ЭтотОбъект);
	ОбщегоНазначенияКлиент.ПоказатьПодтверждениеЗакрытияФормы(Оповещение, Отказ, ЗавершениеРаботы);
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
	
	Если ИмяСобытия = "АдресныйКлассификаторАктуализирован" ИЛИ ИмяСобытия = "ЗагруженАдресныйКлассификатор" Тогда
		
		СообщениеОНеобходимостиЗагрузкиКлассификатора();
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
	Если ТипЗнч(ВыбранноеЗначение) = Тип("Структура") 
		И ВыбранноеЗначение.Свойство("КраткоеПредставлениеОшибки")
		И ЗначениеЗаполнено(ВыбранноеЗначение.КраткоеПредставлениеОшибки) Тогда
			ПоказатьПредупреждение(, ВыбранноеЗначение.КраткоеПредставлениеОшибки);
	КонецЕсли;
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиСобытийЭлементовШапкиФормы

&НаКлиенте
Процедура СтранаПриИзменении(Элемент)
	
	ОтобразитьЭлементыФормыВСоответствиеСоСтраной();
	
КонецПроцедуры

&НаКлиенте
Процедура СтранаОчистка(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура СтранаАвтоПодбор(Элемент, Текст, ДанныеВыбора, Ожидание, СтандартнаяОбработка)
	
	Если Ожидание = 0 Тогда
		// Формирование списка быстрого выбора.
		Если ПустаяСтрока(Текст) Тогда
			ДанныеВыбора = Новый СписокЗначений;
		КонецЕсли;
		Возврат;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура СтранаОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, СтандартнаяОбработка)
	
	Если ПустаяСтрока(Текст) Тогда
		СтандартнаяОбработка = Ложь;
	КонецЕсли;
	
#Если ВебКлиент Тогда
	// Обход особенности платформы.
	СтандартнаяОбработка = Ложь;
	ДанныеВыбора         = Новый СписокЗначений;
	ДанныеВыбора.Добавить(Страна);
#КонецЕсли

КонецПроцедуры

&НаКлиенте
Процедура СтранаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	Если ТипЗнч(ВыбранноеЗначение) = Тип("Структура") И ВыбранноеЗначение.Свойство("Код") Тогда
		НаселенныйПунктДетально.CountryCode = ВыбранноеЗначение.Код;
	Иначе
		НаселенныйПунктДетально.CountryCode = КодСтраны(ВыбранноеЗначение);
	КонецЕсли;
	
	УправлениеКонтактнойИнформациейКлиент.СтранаМираОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка);
	
КонецПроцедуры

&НаКлиенте
Процедура ИндексНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)

	Если МеждународныйФорматАдреса Тогда
		СтандартнаяОбработка = Ложь;
		ДанныеВыбора = Новый СписокЗначений;
		Возврат;
	КонецЕсли;
	
	Если СтрДлина(Индекс) = 6 Тогда
		ФормаВыбораУлицПоИндексу(Индекс);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ИндексИзменениеТекстаРедактирования(Элемент, Текст, СтандартнаяОбработка)
	
	Если МеждународныйФорматАдреса Тогда
		Возврат;
	КонецЕсли;
	
	Если СтрДлина(СокрЛП(Текст)) = 6 И СтрСравнить(Индекс, Текст) <> 0 И Страна = ОсновнаяСтрана Тогда
		СтандартнаяОбработка = Ложь;
		НаселенныйПунктДетально.ZipCode = Текст;
		ФормаВыбораУлицПоИндексу(Текст);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ИндексОкончаниеВводаТекста(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, СтандартнаяОбработка)

	НаселенныйПунктДетально.ZipCode = Текст;
	
	Если МеждународныйФорматАдреса Тогда
		Возврат;
	КонецЕсли;
	
	Если СтрДлина(СокрЛП(Текст)) = 6 И СтрСравнить(Индекс, Текст) <> 0 И Страна = ОсновнаяСтрана Тогда
		СтандартнаяОбработка = Ложь;
		ФормаВыбораУлицПоИндексу(Текст);
	Иначе
		Индекс = Текст;
		ОбновитьПредставлениеАдреса();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ИндексПриИзменении(Элемент)
	НаселенныйПунктДетально.ZipCode = Индекс;
	ОбновитьПредставлениеАдреса();
КонецПроцедуры

&НаКлиенте
Процедура ОКТМОПриИзменении(Элемент)
	НаселенныйПунктДетально.OKTMO = ОКТМО;
КонецПроцедуры

&НаКлиенте
Процедура КомментарийПриИзменении(Элемент)
	
	НаселенныйПунктДетально.Comment = Комментарий;
	ПодключитьОбработчикОжидания("УстановитьПиктограммуКомментария", 0.1, Истина);
	
КонецПроцедуры

&НаКлиенте
Процедура ТипДомаПриИзменении(Элемент)
	
	Если СтрСравнить(ТипДома, РаботаСАдресамиКлиентСервер.НаименованиеЗемельногоУчастка()) <> 0 Тогда
		НаселенныйПунктДетально.HouseType = ТипДома;
		
		Элементы.ТипСтроения.Доступность = Истина;
		Элементы.Строение.Доступность    = Истина;
			
		Если ЗначениеЗаполнено(НаселенныйПунктДетально.stead) Тогда
			НаселенныйПунктДетально.HouseNumber = НаселенныйПунктДетально.stead;
			НаселенныйПунктДетально.stead   = "";
			НаселенныйПунктДетально.steadId = "";
			ОбновитьПредставлениеАдреса();
		ИначеЕсли ЗначениеЗаполнено(НаселенныйПунктДетально.HouseNumber) Тогда
			ОбновитьПредставлениеАдреса();
		КонецЕсли;
		
	Иначе
		НаселенныйПунктДетально.HouseType = "";
		Элементы.ТипСтроения.Доступность = Ложь;
		Элементы.Строение.Доступность    = Ложь;
		
		Если ЗначениеЗаполнено(НаселенныйПунктДетально.HouseNumber) 
			Или НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
				НаселенныйПунктДетально.stead = НаселенныйПунктДетально.HouseNumber;
				НаселенныйПунктДетально.HouseNumber = "";
				НаселенныйПунктДетально.HouseId     = "";
				Строение = "";
				НаселенныйПунктДетально.buildings.Очистить();
				ОбновитьПредставлениеАдреса();
				ПодключитьОбработчикОжидания("ОтобразитьДополнительныеЗданияКлиент", 0.1, Истина);
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ДомПриИзменении(Элемент)
	
	Если ЭтоЗемельныйУчасток(ТипДома) Тогда
		НаселенныйПунктДетально.stead = Дом;
	Иначе
		НаселенныйПунктДетально.HouseNumber = Дом;
		Если ПустаяСтрока(НаселенныйПунктДетально.HouseType) Тогда
			НаселенныйПунктДетально.HouseType = ТипДома;
		КонецЕсли;
	КонецЕсли;
	
	НайденныйИдентификатор = ИдентификаторАдреса(НаселенныйПунктДетально, Истина);
	Если ЗначениеЗаполнено(НайденныйИдентификатор) Тогда
		НайденныйИндекс = НайтиИндексУДома(НайденныйИдентификатор, Дом);
		Если ЗначениеЗаполнено(НайденныйИндекс) Тогда
			Индекс = НайденныйИндекс;
			НаселенныйПунктДетально.ZipCode = Индекс;
		КонецЕсли;
	КонецЕсли;
	
	ЗаполнитьУровниДомовИЗемельныхУчастков();
	ОбновитьПредставлениеАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура ДомОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
		СтандартнаяОбработка = Ложь;
		ЗаполнитьПоляДомовСтроенийЗемельныхУчастков(ВыбранноеЗначение);
		Элементы.Дом.ОбновитьТекстРедактирования();
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура СтроениеОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
		СтандартнаяОбработка = Ложь;
		ЗаполнитьПоляДомовСтроенийЗемельныхУчастков(ВыбранноеЗначение);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ТипСтроенияПриИзменении(Элемент)
	
	Если НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
		НаселенныйПунктДетально.buildings[0].Type = ТипСтроения;
	КонецЕсли;
	
	ОбновитьМенюДобавленияСтроенийИПомещений();
	
	ОбработкаИзмененияАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура СтроениеПриИзменении(Элемент)
	
	ЭтоНовый = Истина;
	Для каждого Помещения Из НаселенныйПунктДетально.buildings Цикл
		Если СтрСравнить(Помещения.Type, ТипСтроения) = 0 Тогда
			Помещения.Type = ЭтотОбъект["ТипСтроения"];
			Помещения.number = Строение;
			ЭтоНовый = Ложь;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если ЭтоНовый Тогда
		ИнформацияОСтроении = ЗначениеСтроенияИлиПомещения(ТипСтроения, Строение);
		НаселенныйПунктДетально.buildings.Вставить(0, ИнформацияОСтроении);
	ИначеЕсли ПустаяСтрока(ЭтотОбъект[Элемент.Имя]) Тогда
		Для ИндексПозиции = 0 По НаселенныйПунктДетально.buildings.Количество() - 1 Цикл
			СведенияОСтроении = НаселенныйПунктДетально.buildings[ИндексПозиции];
			Если СтрСравнить(СведенияОСтроении.Type, ЭтотОбъект["ТипСтроения"]) =0 Тогда
				НаселенныйПунктДетально.buildings.Удалить(ИндексПозиции);
				Прервать;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ОбновитьПредставлениеАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура СтроениеАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	
	Если ЗначениеЗаполнено(Текст) Тогда
			
			Идентификатор = ИдентификаторАдреса(НаселенныйПунктДетально, Истина);
			
			Если ЗначениеЗаполнено(Идентификатор) Тогда
				ДанныеВыбора = СписокАвтоподбораВариантовДомов(Идентификатор, Дом);
				Если ДанныеВыбора.Количество() > 1 Тогда
					СтандартнаяОбработка = Ложь;
				КонецЕсли;
			КонецЕсли;
			
	КонецЕсли;
		
КонецПроцедуры

&НаКлиенте
Процедура ТипСтроенияОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
		
	Отбор = Новый Структура("Значение", ВыбранноеЗначение);
	НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Отбор);
	
	Если НайденныеСтроки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Если НайденныеСтроки[0].Видимость = Ложь Тогда
		СтандартнаяОбработка = Ложь;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ТипПомещенияПриИзменении(Элемент)
	
	Если Элемент.ВыделенныйТекст = НаименованиеПриДобавлениеПроизвольногоПомещения() Тогда
		ЭтотОбъект[Элемент.Имя] = "";
	КонецЕсли;
	
	Если ПустаяСтрока(Помещение) Тогда
		ОбновитьМенюДобавленияСтроенийИПомещений();
		Возврат;
	КонецЕсли;
	
	Если НаселенныйПунктДетально.Apartments.Количество() > 0 Тогда
		НаселенныйПунктДетально.Apartments[0].Type = ТипПомещения;
	КонецЕсли;
	
	Если ПустаяСтрока(ЭтотОбъект[Элемент.Имя]) Тогда
		УдалитьПомещениеИзАдреса(ЭтотОбъект["ТипПомещения"]);
	КонецЕсли;
	
	ОбновитьМенюДобавленияСтроенийИПомещений();
	
	ОбработкаИзмененияАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура ПомещениеПриИзменении(Элемент)
	
	ОбновитьДополнительныеЗдания = Истина;
	Если ПустаяСтрока(ЭтотОбъект[Элемент.Имя]) Тогда
		УдалитьПомещениеИзАдреса(ЭтотОбъект["ТипПомещения"]);
	Иначе
		ИнформацияОПомещении = ЗначениеСтроенияИлиПомещения(ТипПомещения, Помещение);
		Если НаселенныйПунктДетально.Apartments.Количество() = 0 Тогда
			НаселенныйПунктДетально.Apartments.Добавить(ИнформацияОПомещении);
			ОбновитьДополнительныеЗдания = Ложь;
		Иначе
			Если СтрСравнить(НаселенныйПунктДетально.Apartments[0].type, ТипПомещения) = 0 Тогда
				НаселенныйПунктДетально.Apartments[0] = ИнформацияОПомещении;
				ОбновитьДополнительныеЗдания = Ложь;
			Иначе
				НаселенныйПунктДетально.Apartments.Вставить(0, ИнформацияОПомещении);
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
	ОбработкаИзмененияАдреса(ОбновитьДополнительныеЗдания);
	
КонецПроцедуры

&НаКлиенте
Процедура ТипПомещенияОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	Отбор = Новый Структура("Значение", ВыбранноеЗначение);
	НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Отбор);
	
	Если НайденныеСтроки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	Если НайденныеСтроки[0].Видимость = Ложь Тогда
		СтандартнаяОбработка = Ложь;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура НаселенныйПунктПриИзменении(Элемент)
	
	ИзменитьСведенияОНаселенномПункте();
	
КонецПроцедуры

&НаКлиенте
Процедура НаселенныйПунктОчистка(Элемент, СтандартнаяОбработка)
	
	ОчиститьНаселенныйПункт();
	
КонецПроцедуры

&НаКлиенте
Процедура НаселенныйПунктНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	
	// Если пришли впрямую после редактирования, то сбрасываем адрес.
	Если Элемент.ТекстРедактирования <> НаселенныйПункт Тогда
		Модифицированность = Истина;
		НаселенныйПункт    = Элемент.ТекстРедактирования;
		ИзменитьСведенияОНаселенномПункте();
		ИдентификаторНаселенногоПункта = Неопределено;
	КонецЕсли;
	
	ПараметрыФормы = ПараметрыОткрытияФормыНаселенногоПункта();
	
	Оповещение = Новый ОписаниеОповещения("ПослеВводаСведенийНаселенногоПункта", ЭтотОбъект);
	
	ОткрытьФорму("Обработка.РасширенныйВводКонтактнойИнформации.Форма.НаселенныйПунктАдреса", ПараметрыФормы, 
		Элемент,,,, Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	
КонецПроцедуры


&НаКлиенте
Процедура НаселенныйПунктОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Если ВыбранноеЗначение = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Модифицированность = Истина;
	
	Если ТипЗнч(ВыбранноеЗначение) <> Тип("Структура") Тогда
		Возврат;
	КонецЕсли;
	
	Если ЕстьПравоЗагружатьКлассификатор И ВыбранноеЗначение.ПредлагатьЗагрузкуКлассификатора = Истина Тогда
		// Предлагаем загрузить классификатор.
		ПредложениеЗагрузкиКлассификатора(СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Данные для ""%1"" не загружены.'"), 
			ВыбранноеЗначение.Представление), ВыбранноеЗначение);
	Иначе
		УстановитьНаселенныйПунктПослеВыбора(ВыбранноеЗначение);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура НаселенныйПунктАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	
	Если МеждународныйФорматАдреса Тогда
		Возврат;
	КонецЕсли;
	
	ДанныеВыбора = Новый СписокЗначений;
	
	ТекстДляАвтоПодбора = СокрЛП(Текст);
	Если СтрДлина(ТекстДляАвтоПодбора) < 3 Или Не РаботаСАдресамиКлиентСервер.ЭтоОсновнаяСтрана(Страна) Тогда
		// Нет вариантов, список пуст, стандартную обработку не надо трогать.
		Возврат;
	КонецЕсли;
	
	Результат = СписокАвтоподбораНаселенногоПункта(ТекстДляАвтоПодбора, ТипАдреса);
	Если Результат.Отказ Тогда
		Возврат;
	КонецЕсли;
	
	ДанныеВыбора = Результат.Данные;
	// Стандартную обработку отключаем, только если есть наши варианты.
	Если ДанныеВыбора.Количество() > 0 Тогда
		СтандартнаяОбработка = Ложь;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура УлицаПриИзменении(Элемент)
	
	ОбновитьСписокУровней(НаселенныйПунктДетально, "street", ЗначениеЗаполнено(Улица));
	
	Если Не ЭтоРФАдрес() Или МеждународныйФорматАдреса Тогда
		
		НаселенныйПунктДетально.Street = Улица;
		ОбновитьПредставлениеАдреса();
		Возврат;
		
	КонецЕсли;
	
	ЧастиАдреса = СтрРазделить(Улица, " ");
	Если ЧастиАдреса.Количество() > 1 Тогда
		ТипОбъекта = ЧастиАдреса[0];
		ЧастиАдреса.Удалить(0);
	Иначе
		ТипОбъекта = "";
	КонецЕсли;
	
	Наименование = СокрЛП(СтрСоединить(ЧастиАдреса, " "));
	
	НаселенныйПунктДетально.Street     = Наименование;
	НаселенныйПунктДетально.StreetType = ТипОбъекта;
	НаселенныйПунктДетально.StreetID   = "";
	
	ОбновитьПредставлениеАдреса();
	
	УстановитьИдентификаторыАдреса(НаселенныйПунктДетально);
	
КонецПроцедуры

&НаКлиенте
Процедура УлицаНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	
	// Если пришли впрямую после редактирования, то сбрасываем.
	Если Элемент.ТекстРедактирования <> Улица Тогда
		Улица = Элемент.ТекстРедактирования;
	КонецЕсли;
	
	ИдентификаторНаселенногоПункта = ИдентификаторАдреса(НаселенныйПунктДетально, Ложь);
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("Родитель",  ИдентификаторНаселенногоПункта);
	ПараметрыФормы.Вставить("Уровень",   РаботаСАдресамиКлиентСервер.СопоставлениеНаименованиеУровнюАдреса("STREET"));
	ПараметрыФормы.Вставить("ТипАдреса", НаселенныйПунктДетально.AddressType);
	
	Оповещение = Новый ОписаниеОповещения("ПослеВыбораУлицы", ЭтотОбъект);
	
	ОткрытьФорму("Обработка.РасширенныйВводКонтактнойИнформации.Форма.ВыборАдресаПоУровню", ПараметрыФормы, ЭтотОбъект,
		,,, Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	
КонецПроцедуры


&НаКлиенте
Процедура УлицаОбработкаВыбора(Элемент, ВыбранноеЗначение, СтандартнаяОбработка)
	
	Если Страна <> ОсновнаяСтрана Тогда
		Возврат;
	КонецЕсли;
	
	СтандартнаяОбработка = Ложь;
	
	Если ВыбранноеЗначение = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Модифицированность = Истина;
	ТипЗначения = ТипЗнч(ВыбранноеЗначение);
	
	Если ТипЗначения = Тип("УникальныйИдентификатор") Тогда
		СведенияОбАдресе = Новый Структура("Идентификатор", ВыбранноеЗначение);
	ИначеЕсли ТипЗначения = Тип("Структура") Тогда
		СведенияОбАдресе = ВыбранноеЗначение;
	КонецЕсли;
	СведенияОбАдресе.Вставить("Муниципальный", РаботаСАдресамиКлиентСервер.ЭтоМуниципальныйАдрес(НаселенныйПунктДетально.addressType));
	СведенияОбАдресе.Вставить("Адрес", НаселенныйПунктДетально);
	
	НаселенныйПунктУстановитьПоляАдреса(НаселенныйПунктДетально, СведенияОбАдресе, Истина);
	ОбработкаИзмененияАдреса();
	Элементы.Улица.ОбновитьТекстРедактирования();
	
КонецПроцедуры

&НаКлиенте
Процедура УлицаАвтоПодбор(Элемент, Текст, ДанныеВыбора, Ожидание, СтандартнаяОбработка)
	
	Если Не АвтоподборДоступен Тогда
		Возврат;
	КонецЕсли;
	
	ДанныеВыбора = Новый СписокЗначений;
	
	ИдентификаторНаселенногоПункта = ИдентификаторАдреса(НаселенныйПунктДетально, Ложь);
	Если СтрДлина(Текст) < 2 Или Не ЗначениеЗаполнено(ИдентификаторНаселенногоПункта)Тогда
		// Нет вариантов, список пуст, стандартную обработку не надо трогать.
		Возврат;
	КонецЕсли;
	
	Результат = ВариантыУлицПоТексту(Текст);

	Если Результат.Отказ Тогда
		Возврат;
	КонецЕсли;
	
	Если Результат.Данные.Количество() = 0 Тогда
		АдаптацияИдентификатораНаселенногоПункта(ИдентификаторНаселенногоПункта);
		Результат = ВариантыУлицПоТексту(Текст);

		Если Результат.Отказ Тогда
			Возврат;
		КонецЕсли;
	КонецЕсли;
	
	ДанныеВыбора = Результат.Данные;
	
	// Стандартную обработку отключаем, только если есть наши варианты.
	Если ДанныеВыбора.Количество() > 0 Тогда
		СтандартнаяОбработка = Ложь;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура УлицаОчистка(Элемент, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	НаселенныйПунктДетально.streetID   = "";
	НаселенныйПунктДетально.street     = "";
	НаселенныйПунктДетально.streetType = "";
	Улица                              = "";
	
КонецПроцедуры

&НаКлиенте
Процедура ПредставлениеИностранногоАдресаПриИзменении(Элемент)
	
	НаселенныйПунктДетально.value = ПредставлениеАдреса;
	
КонецПроцедуры

// Дом, помещения

&НаКлиенте
Процедура ДомАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	
	Если Не АвтоподборДоступен Тогда
		Возврат;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Текст) Тогда
		Идентификатор = ИдентификаторАдреса(НаселенныйПунктДетально, Истина);
		Если ЗначениеЗаполнено(Идентификатор) Тогда
			
			Если СтрСравнить(ТипДома, РаботаСАдресамиКлиентСервер.НаименованиеЗемельногоУчастка()) <> 0 Тогда
				ДанныеВыбора = СписокАвтоподбораВариантовДомов(Идентификатор, Текст + "%");
			Иначе
				ДанныеВыбора = СписокАвтоподбораЗемельныхУчастков(Идентификатор, Текст + "%");
			КонецЕсли;
			
			Если ДанныеВыбора.Количество() > 0 Тогда
				СтандартнаяОбработка = Ложь;
			КонецЕсли;
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура АдресНаДатуАвтоПодбор(Элемент, Текст, ДанныеВыбора, ПараметрыПолученияДанных, Ожидание, СтандартнаяОбработка)
	Если СтрСравнить(Текст, НачалоУчета()) = 0 Или ПустаяСтрока(Текст) Тогда
		Элементы.АдресНаДату.ФорматРедактирования = "";
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура АдресНаДатуПриИзменении(Элемент)
	
	Если Не ВводНовогоАдреса Тогда
		
		Отбор = Новый Структура("Вид", ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).Ссылка);
		НайденныеСтроки = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
		Результат = ОпределитьДатуДействия(АдресНаДату, НайденныеСтроки);
		
		Если Результат.ТекущаяСтрока <> Неопределено Тогда
			Тип = Результат.ТекущаяСтрока.Тип;
			АдресДействуетС = Результат.ДействуетС;
			НаселенныйПунктДетально = АдресСИсторией(Результат.ТекущаяСтрока.Значение);
		Иначе
			Тип = ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.Адрес");
			АдресДействуетС = АдресНаДату;
			НаселенныйПунктДетально = РаботаСАдресамиКлиентСервер.ОписаниеНовойКонтактнойИнформации(Тип);
		КонецЕсли;
		
		ОбработкаИзмененияАдреса();
		
		Если ЗначениеЗаполнено(Результат.ДействуетПо) Тогда
			ТекстИсторическийАдрес = " " + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'действует по %1'"), Формат(Результат.ДействуетПо - 10, "ДЛФ=DD"));
		Иначе
			ТекстИсторическийАдрес = НСтр("ru = 'действует по настоящее время.'");
		КонецЕсли;
		Элементы.ТекстПроДатуДействия.Заголовок = ТекстИсторическийАдрес;
	Иначе
		АдресДействуетС = АдресНаДату;
	КонецЕсли;
	
	ТекстНачалаУчета = НачалоУчета();
	Элементы.АдресНаДату.ФорматРедактирования = ?(ЗначениеЗаполнено(АдресНаДату), "", "ДФ='""" + ТекстНачалаУчета  + """'");
	
КонецПроцедуры


&НаКлиенте
Процедура ИнформацияОЗагрузкеАдресныеСведенийОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	СтандартнаяОбработка = Ложь;
	Если НавигационнаяСсылкаФорматированнойСтроки = "load"
		И ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		
			Оповещение = Новый ОписаниеОповещения("ПослеАвторизоватьНаСайтеПоддержкиПользователей", ЭтотОбъект);
			МодульАдресныйКлассификаторКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("АдресныйКлассификаторКлиент");
			МодульАдресныйКлассификаторКлиент.АвторизоватьНаСайтеПоддержкиПользователей(Оповещение, ЭтотОбъект);
		
	КонецЕсли;
	
КонецПроцедуры


&НаКлиенте
Процедура ДекорацияНужнаПомощьОбработкаНавигационнойСсылки(Элемент, НавигационнаяСсылкаФорматированнойСтроки, СтандартнаяОбработка)
	
	Если СтрНайти(НавигационнаяСсылкаФорматированнойСтроки, ".СведенияОбАдресномКлассификаторе") > 0
		И ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
			СтандартнаяОбработка = Ложь;
			
			ПараметрыОткрытия = Новый Структура();
			ПараметрыОткрытия.Вставить("Адрес", ПредставлениеАдреса);
			ПараметрыОткрытия.Вставить("СведенияОбАдресе", СведенияОбАдресе(НаселенныйПунктДетально));
			
			МодульАдресныйКлассификаторКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("АдресныйКлассификаторКлиент");
			МодульАдресныйКлассификаторКлиент .ОткрытьСведенияОбАдресномКлассификаторе(ПараметрыОткрытия);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ДомНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	ПоказатьСписокДомовИлиЗемельныхУчастков(Ложь);
КонецПроцедуры

&НаКлиенте
Процедура СтроениеНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
	ПоказатьСписокДомовИлиЗемельныхУчастков(Истина);
КонецПроцедуры

#КонецОбласти

#Область ОбработчикиКомандФормы

&НаКлиенте
Процедура КомандаОК(Команда)
	ПодтвердитьИЗакрыть();
КонецПроцедуры

&НаКлиенте
Процедура КомандаОтмена(Команда)
	Модифицированность = Ложь;
	Закрыть();
КонецПроцедуры

&НаКлиенте
Процедура ПроверитьЗаполнениеАдреса(Команда)
	
	Если РазрешитьВводАдресаВСвободнойФорме Тогда
		ПоказатьПредупреждение(, НСтр("ru = 'Адрес не может быть проверен, так как он введен в свободной форме.'"));
		Возврат;
	КонецЕсли;

	ПредупреждатьОбОтсутствииОшибок = Истина;
	ТребуетсяОбновление = Ложь;
	
	СписокОшибок = СписокОшибокЗаполнения(НаселенныйПунктДетально, ВидКонтактнойИнформации, ПредупреждатьОбОтсутствииОшибок, ТребуетсяОбновление);
	СообщитьОбОшибкахЗаполнения(СписокОшибок, ПредупреждатьОбОтсутствииОшибок, ТребуетсяОбновление);
	
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьАдрес(Команда)
	
	ОчиститьАдресКлиент();
	ОбработкаИзмененияАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьПоПочтовомуИндексу(Команда)
	
	Если ЕстьЗагруженныйКлассификатор И СтрДлина(Индекс) = 6 Тогда
		ФормаВыбораУлицПоИндексу(Индекс);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ЗагрузитьКлассификатор(Команда)
	
	ОткрытьФормуЗагрузкиКлассификатора();
	
КонецПроцедуры

&НаКлиенте
Процедура ВвестиАдресВСвободнойФорме(Команда)
	
	ЭтоНациональныйАдрес = РаботаСАдресамиКлиентСервер.ЭтоМуниципальныйАдрес(НаселенныйПунктДетально.addressType)
		Или РаботаСАдресамиКлиент.ЭтоАдминистративноТерриториальныйАдрес(НаселенныйПунктДетально.addressType);
		
	Если РазрешитьВводАдресаВСвободнойФорме Тогда
		ПереключитьНаСтруктурированныйВвод();
	ИначеЕсли ЭтоНациональныйАдрес Тогда
		ТекстВопроса = НСтр("ru = 'Ввести адрес в свободной форме?
		                        |Адреса, введенные в свободной форме, могут не пройти проверку по адресному классификатору.'");
		Оповещение = Новый ОписаниеОповещения("ВвестиАдресВСвободнойФормеЗавершение", ЭтотОбъект);
		ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет, , , НСтр("ru = 'Подтверждение'"));
	Иначе
		ПереключитьАдресВСвободнойФорму();
	КонецЕсли;
	
КонецПроцедуры



&НаКлиенте
Процедура АвторизацияНаСайтеПоддержкиПользователей(Команда)
	
	ОповещениеОЗакрытии = Новый ОписаниеОповещения("АвторизацияНаСайтеПоддержкиПользователейЗавершение", ЭтотОбъект);
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("ИнтернетПоддержкаПользователей") Тогда
		МодульИнтернетПоддержкаПользователейКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("ИнтернетПоддержкаПользователейКлиент");
		МодульИнтернетПоддержкаПользователейКлиент.ПодключитьИнтернетПоддержкуПользователей(ОповещениеОЗакрытии, ЭтотОбъект);
	КонецЕсли
	
КонецПроцедуры

&НаКлиенте
Процедура ИсторияИзменений(Команда)
	
	ДополнительныеПараметры = Новый Структура;
	
	ОписаниеДополнительныхРеквизитов = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов;
	
	СписокКонтактнойИнформации = ЗаполнитьСписокКонтактнойИнформации(ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).Ссылка, ОписаниеДополнительныхРеквизитов);
	
	ПараметрыФормы = Новый Структура("СписокКонтактнойИнформации", СписокКонтактнойИнформации);
	ПараметрыФормы.Вставить("ВидКонтактнойИнформации", ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).Ссылка);
	ПараметрыФормы.Вставить("ТолькоПросмотр", ТолькоПросмотр);
	ПараметрыФормы.Вставить("ИзФормыВводаАдреса", Истина);
	ПараметрыФормы.Вставить("ДействуетС", АдресНаДату);
	
	ОповещениеОЗакрытие = Новый ОписаниеОповещения("ПослеЗакрытияФормыИстории", ЭтотОбъект, ДополнительныеПараметры);
	ОткрытьФорму("Обработка.ВводКонтактнойИнформации.Форма.ИсторияКонтактнойИнформации", ПараметрыФормы, ЭтотОбъект,,,, ОповещениеОЗакрытие);
	
КонецПроцедуры

&НаКлиенте
Процедура АдресНаЯндексКарты(Команда)
	УправлениеКонтактнойИнформациейКлиент.ПоказатьАдресНаКарте(ПредставлениеАдреса, "Яндекс.Карты");
КонецПроцедуры

&НаКлиенте
Процедура АдресНаGoogleMaps(Команда)
	УправлениеКонтактнойИнформациейКлиент.ПоказатьАдресНаКарте(ПредставлениеАдреса, "GoogleMaps");
КонецПроцедуры

&НаКлиенте
Процедура АдресныйКлассификаторУстарел(Команда)
	
	
	СообщениеОПроверкеАдреса = НСтр("ru = 'Адресные сведения, загруженные в программу, устарели.
		|Рекомендуется выполнить обновление адресного классификатор, чтобы проверка адреса выполнялась корректно.'");
	Если ЕстьПравоЗагружатьКлассификатор Тогда
		ВопросОбОбновлениеАдресногоКлассификатора(СообщениеОПроверкеАдреса);
	Иначе
		СообщениеОПроверкеАдреса = СообщениеОПроверкеАдреса + Символы.ПС
			+ НСтр("ru = 'Для обновления адресного классификатора обратитесь к администратору.'");
		ПоказатьПредупреждение(, СообщениеОПроверкеАдреса);
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура АдминистративноТерриториальноеДеление(Команда)
	
	ПереключитьНаСтруктурированныйВвод(РаботаСАдресамиКлиентСервер.АдминистративноТерриториальныйАдрес());
	
КонецПроцедуры

&НаКлиенте
Процедура МуниципальноеДеление(Команда)
	
	ПереключитьНаСтруктурированныйВвод(РаботаСАдресамиКлиентСервер.МуниципальныйАдрес());
	
КонецПроцедуры

&НаКлиенте
Процедура ДобавитьКомментарий(Команда)
	Элементы.ОсновныеСтраницы.ОтображениеСтраниц = ОтображениеСтраницФормы.ЗакладкиСверху;
	Элементы.ОсновныеСтраницы.ТекущаяСтраница = Элементы.СтраницаКомментарий;
КонецПроцедуры

// Параметры:
//  Команда - КомандаФормы
// 
&НаКлиенте
Процедура Подключаемый_ДобавитьСтроениеИлиПомещение(Команда)
	
	ТипСтроенияИлиПомещения = СтрРазделить(Команда.Имя, "_")[1];
	
	Отбор = Новый Структура("Ключ", ТипСтроенияИлиПомещения);
	НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Отбор);
	Если НайденныеСтроки.Количество() = 0 Тогда
		Возврат;
	КонецЕсли;
	
	НайденныеСтроки[0].Видимость = Ложь;
	
	Идентификатор = СтрЗаменить(Новый УникальныйИдентификатор(),"-", "");
	ИмяТекущего = ДобавитьПолеСтроенияИлиПомещения(Идентификатор, НайденныеСтроки[0].Тип,
		НайденныеСтроки[0].Значение);
		
	Если ИмяТекущего <> Неопределено Тогда
		ТекущийЭлемент = Элементы[ИмяТекущего];
	КонецЕсли;
	
	Если НайденныеСтроки[0].Тип = "Помещение" Тогда
		Значение = ?(НайденныеСтроки[0].Значение <> НСтр("ru = 'Другое'"), НайденныеСтроки[0].Значение, "");
		ПомещенияАдреса = НаселенныйПунктДетально.Apartments; // Массив
		ПомещенияАдреса.Добавить(ЗначениеСтроенияИлиПомещения(Значение, ЭтотОбъект[ИмяТекущего]));
	Иначе
		ЗданияАдреса = НаселенныйПунктДетально.buildings;  // Массив
		ЗданияАдреса.Добавить(ЗначениеСтроенияИлиПомещения(НайденныеСтроки[0].Значение, ЭтотОбъект[ИмяТекущего]));
	КонецЕсли;
	
	ОбновитьМенюДобавленияСтроенийИПомещений();
	
КонецПроцедуры

#КонецОбласти

#Область СлужебныеПроцедурыИФункции

&НаСервереБезКонтекста
Функция АдресСИсторией(ЗначенияПолей)
	
	Возврат УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(ЗначенияПолей, Перечисления.ТипыКонтактнойИнформации.Адрес);
	
КонецФункции

// Параметры:
//   Результат - Структура:
//     * Индекс - Строка
//   ДополнительныеПараметры - Произвольный
//
&НаКлиенте
Процедура ПослеВыбораАдресаПоИндексу(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат <> Неопределено Тогда
		
		Если Результат.Отказ Тогда
			Если Результат.Свойство("Индекс") И НЕ ПустаяСтрока(Результат.Индекс) Тогда
				ОбновитьПредставлениеАдреса();
				Возврат;
			Иначе
				Если НЕ ПодборПоИндексуДоступен Тогда
					ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'Индекс %1 не найден в адресном классификаторе'"),
						Формат(Результат.Индекс, "ЧРГ=' '; ЧГ=0"));
					ОбщегоНазначенияКлиент.СообщитьПользователю(ТекстСообщения,,, "Объект.Индекс");
				Иначе
					ПроверитьДоступностьКлассификатора();
				КонецЕсли;
			КонецЕсли;
			Возврат;
		КонецЕсли;
		
		ОчиститьАдресКлиент();
		Если ТипЗнч(Результат) = Тип("Структура") Тогда
			ПолученныйАдрес = ОпределитьАдресПоИдентификатору(Результат);
			ЗаполнитьЗначенияСвойств(НаселенныйПунктДетально, ПолученныйАдрес);
			Если ПустаяСтрока(НаселенныйПунктДетально.ZipCode) Тогда
				НаселенныйПунктДетально.ZipCode = Формат(Результат.Индекс,"ЧГ=0");
			КонецЕсли;
		КонецЕсли;
		
		ОбработкаИзмененияАдреса();
		УстановитьФлагиВМенюПоТипуАдреса();
		
		ТекущийЭлемент = Элементы.Дом;
	Иначе
		ОбновитьПредставлениеАдреса();
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ОтключитьВозможностьВыбораАдресныхСведенийИзКлассификатора()
	
	Элементы.ГруппаИнформация.Видимость            = Ложь;
	Элементы.ПроверитьЗаполнениеАдреса.Видимость   = Ложь;
	Элементы.ЗаполнитьПоПочтовомуИндексу.Видимость = Ложь;
	Элементы.ЗагрузитьКлассификатор.Видимость      = Ложь;
	Элементы.Улица.КнопкаВыбора                    = Ложь;
	Элементы.Дом.КнопкаВыбора                      = Ложь;
	Элементы.Строение.КнопкаВыбора                 = Ложь;
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьУровниДомовИЗемельныхУчастков()
	
	ЗаполненыДома = Ложь;
	
	Если ЗначениеЗаполнено(НаселенныйПунктДетально.houseNumber) 
		 Или НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
			ЗаполненыДома = Истина;
	КонецЕсли;
	
	ОбновитьСписокУровней(НаселенныйПунктДетально, "house", ЗаполненыДома);
	ОбновитьСписокУровней(НаселенныйПунктДетально, "stead", ЗначениеЗаполнено(НаселенныйПунктДетально.stead));
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Процедура ОбновитьСписокУровней(НаселенныйПунктДетально, ИмяУровня, ЕстьЗначение)
	
	Если ИмяУровня <> "district" Тогда
		ПозицияМуниципальныйУровень = НаселенныйПунктДетально.munLevels.Найти(ИмяУровня);
	Иначе
		ПозицияМуниципальныйУровень = -1;
	КонецЕсли;
	
	Если ИмяУровня <> "munDistrict" И ИмяУровня <> "settlement" Тогда
		ПозицияАдминистративнойУровень = НаселенныйПунктДетально.admLevels.Найти(ИмяУровня);
	Иначе
		ПозицияАдминистративнойУровень = -1;
	КонецЕсли;
	
	Если ЕстьЗначение Тогда
		Если ПозицияМуниципальныйУровень = Неопределено Тогда
			НаселенныйПунктДетально.munLevels.Добавить(ИмяУровня);
		КонецЕсли;
		Если ПозицияАдминистративнойУровень = Неопределено Тогда
			НаселенныйПунктДетально.admLevels.Добавить(ИмяУровня);
		КонецЕсли;
	Иначе
		Если ПозицияМуниципальныйУровень <> Неопределено И ПозицияМуниципальныйУровень >= 0 Тогда
			НаселенныйПунктДетально.munLevels.Удалить(ПозицияМуниципальныйУровень);
		КонецЕсли;
		Если ПозицияАдминистративнойУровень <> Неопределено И ПозицияАдминистративнойУровень >= 0 Тогда
			НаселенныйПунктДетально.admLevels.Удалить(ПозицияАдминистративнойУровень);
		КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура УстановитьМуниципальныеСведения(НаселенныйПунктДетально)
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		
		МодульАдресныйКлассификаторСлужебный = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификаторСлужебный");
		МодульАдресныйКлассификаторСлужебный.УстановитьИдентификаторыАдреса(НаселенныйПунктДетально);
		
		ИдентификаторАдреса = ИдентификаторАдреса(НаселенныйПунктДетально, Истина);
		Если ЗначениеЗаполнено(ИдентификаторАдреса) Тогда
			
			СведенияОбАдресномОбъекта = МодульАдресныйКлассификаторСлужебный.СведенияОбАдресномОбъекта(ИдентификаторАдреса);
			Результат = МодульАдресныйКлассификаторСлужебный.АктуальныеАдресныеСведения(СведенияОбАдресномОбъекта);
				
			Если Не Результат.Отказ Тогда
				ДанныеИзКлассификатора = РаботаСАдресами.ПодготовитьАдресДляВвода(Результат.Данные);
				
				ЗаполнитьЗначенияСвойств(НаселенныйПунктДетально, ДанныеИзКлассификатора,
					"munDistrict, munDistrictType,munDistrictId,settlement,settlementType,settlementId");
				
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ВариантыУлицПоТексту(Знач Текст)
	
	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("Идентификатор", ИдентификаторНаселенногоПункта);
	ДополнительныеПараметры.Вставить("ТипАдреса",     НаселенныйПунктДетально.AddressType);
	ДополнительныеПараметры.Вставить("Уровень",       8);
	
	Результат = СписокАвтоподбораУлицы(Текст, ДополнительныеПараметры);
	Возврат Результат;

КонецФункции

&НаКлиенте
Процедура ФормаВыбораУлицПоИндексу(Знач Текст)
	
	Если Не ЭтоРФАдрес() Тогда
		Возврат;
	КонецЕсли;
	
	Модифицированность = Истина;
	Индекс = Текст;
	
	Если АвтоподборДоступен Тогда
		
		ПараметрыФормы = ПараметрыОткрытияФормаВыбораПоИндексу();
		ПараметрыФормы.Индекс =СокрЛП(Текст);
		
		Оповещение = Новый ОписаниеОповещения("ПослеВыбораАдресаПоИндексу", ЭтотОбъект);
		ОткрытьФорму("Обработка.РасширенныйВводКонтактнойИнформации.Форма.ВыборАдресаПоПочтовомуИндексу", ПараметрыФормы, Элементы.Индекс,,,, Оповещение);
	Иначе
		ОбновитьПредставлениеАдреса();
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Функция ЭтоРФАдрес()
	
	Возврат РаботаСАдресамиКлиентСервер.ЭтоМуниципальныйАдрес(НаселенныйПунктДетально.addressType)
		Или РаботаСАдресамиКлиент.ЭтоАдминистративноТерриториальныйАдрес(НаселенныйПунктДетально.addressType);
	
КонецФункции

&НаКлиенте
Процедура ВвестиАдресВСвободнойФормеЗавершение(Знач РезультатВопроса, Знач ДополнительныеПараметры) Экспорт
	
	Если РезультатВопроса <> КодВозвратаДиалога.Да Тогда
		Возврат;
	КонецЕсли;
	
	ПереключитьАдресВСвободнойФорму();
	
КонецПроцедуры

&НаКлиенте
Процедура ПереключитьАдресВСвободнойФорму()
	
	Элементы.ПроверитьЗаполнениеАдреса.Доступность = Ложь;
	
	Если Элементы.АдресПредставлениеКомментарий.ТекущаяСтраница = Элементы.НациональныйАдрес Тогда
		РазрешитьВводАдресаВСвободнойФорме = Истина;
		ПоказатьАдресВСвободнойФорме();
		Возврат;
	КонецЕсли;
		
	РазрешитьВводАдресаВСвободнойФорме = Ложь;
	Элементы.АдресПредставлениеКомментарий.ТекущаяСтраница = Элементы.НациональныйАдрес;
	
	Если Не УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType) Тогда
		ОтобразитьВыбранныйТипАдреса(НаселенныйПунктДетально.AddressType);
		Возврат;
	КонецЕсли;
		
	Если РаботаСАдресамиКлиентСервер.ЭтоОсновнаяСтрана(Страна) Тогда
		// Попытка восстановить адрес по полям из представления.
		НаселенныйПунктДетально = КонтактнаяИнформацияПоПредставлению(ПредставлениеАдреса, Комментарий, Истина);
		ОтобразитьВыбранныйТипАдреса(НаселенныйПунктДетально.AddressType);
		Возврат;
	КонецЕсли;
		
	ЧастиАдреса = СтрРазделить(ПредставлениеАдреса, ",");
	Если СтрСравнить(Страна, ЧастиАдреса[0]) = 0 Тогда
		ЧастиАдреса.Удалить(0);
	КонецЕсли;
	
	Если ЧастиАдреса.Количество() > 1 Тогда
		ЧастьУлица = СокрЛП(ЧастиАдреса[ЧастиАдреса.Количество() - 1]);
		ЧастиАдреса.Удалить(ЧастиАдреса.Количество() - 1);
	Иначе
		ЧастьУлица = "";
	КонецЕсли;
	
	ЧастьГород = СокрЛП(?(ЧастиАдреса.Количество() > 0, СтрСоединить(ЧастиАдреса, ","), ""));
	
	Если СведенияОСтране.УчастникЕАЭС Тогда
		НаселенныйПунктДетально.AddressType = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС();
		НаселенныйПунктДетально.Area = ЧастьГород;
	Иначе
		НаселенныйПунктДетально.AddressType = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес();
		НаселенныйПунктДетально.City = ЧастьГород;
	КонецЕсли;
	НаселенныйПунктДетально.Street = ЧастьУлица;
	
	ОтобразитьВыбранныйТипАдреса(НаселенныйПунктДетально.AddressType);
	
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьНаселенныйПункт()
	
	ИдентификаторНаселенногоПункта = Неопределено;
	
	УровниАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса("Все", Ложь);
	Для каждого ИмяУровня Из УровниАдреса Цикл
		Если НаселенныйПунктДетально.Свойство(ИмяУровня) Тогда
			НаселенныйПунктДетально[ИмяУровня] = "";
			НаселенныйПунктДетально[ИмяУровня + "Type"] = "";
			НаселенныйПунктДетально[ИмяУровня + "Id"] = "";
			ОбновитьСписокУровней(НаселенныйПунктДетально, ИмяУровня, Ложь);
		КонецЕсли;
	КонецЦикла;
	
	ОчиститьИдентификаторыАдреса();
	ОбновитьПредставлениеАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура ОтобразитьЭлементыФормыВСоответствиеСоСтраной()
	
	СведенияОСтране = СведенияОСтране(Страна);
	Если Не УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType) Тогда
		
		ТипАдреса = НаселенныйПунктДетально.AddressType;
		КоличествоПолейПредыдущийТипАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(НаселенныйПунктДетально.AddressType, Ложь).Количество();
		
		ПереопределитьТипаАдресаПоСтране(Страна, НаселенныйПунктДетально, СведенияОСтране, МеждународныйФорматАдреса);
		
		КоличествоПолейНовыйТипАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(НаселенныйПунктДетально.AddressType, Ложь).Количество();
		
		Если КоличествоПолейПредыдущийТипАдреса > КоличествоПолейНовыйТипАдреса Тогда
			ПеренестиЗначенияПолейАдресВПоляНовогоТипа(ТипАдреса);
		КонецЕсли;
		
	КонецЕсли;
	
	ОтобразитьПоляПоТипуАдреса();
	
	Если РаботаСАдресамиКлиентСервер.ЭтоОсновнаяСтрана(Страна) И Не МеждународныйФорматАдреса Тогда
		
		Восстановлен = ВосстановитьАдрес(ПредставлениеАдреса, НаселенныйПунктДетально, НаселенныйПунктДетально.AddressType);
		
		Если Восстановлен Тогда
			ОбновитьПредставлениеАдреса();
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Функция ВосстановитьАдрес(ПредставлениеАдреса, НаселенныйПункт, ТипАдреса)
	
	Результат = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияПоПредставлению(ПредставлениеАдреса, Перечисления.ТипыКонтактнойИнформации.Адрес);
	
	ВосстановленныйАдрес = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(Результат, Перечисления.ТипыКонтактнойИнформации.Адрес);
	Если УправлениеКонтактнойИнформацией.АдресВведенВСвободнойФорме(ВосстановленныйАдрес) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	ВосстановленныйАдрес.AddressType = ТипАдреса;
	ЗаполнитьЗначенияСвойств(НаселенныйПунктДетально, ВосстановленныйАдрес);
	УстановитьЗначениеРеквизитовПоКонтактнойИнформации(НаселенныйПунктДетально);
	
	Возврат Истина;
	
КонецФункции


&НаКлиентеНаСервереБезКонтекста
Процедура ПереопределитьТипаАдресаПоСтране(Страна, НаселенныйПунктДетально, СведенияОСтране, МеждународныйФорматАдреса)
	
	Если РаботаСАдресамиКлиентСервер.ЭтоОсновнаяСтрана(Страна) И Не МеждународныйФорматАдреса Тогда
		Если СтрСравнить(НаселенныйПунктДетально.AddressType, РаботаСАдресамиКлиентСервер.АдминистративноТерриториальныйАдрес()) <> 0 Тогда
			НаселенныйПунктДетально.AddressType = РаботаСАдресамиКлиентСервер.МуниципальныйАдрес();
		КонецЕсли;
	ИначеЕсли СведенияОСтране.УчастникЕАЭС Тогда
		НаселенныйПунктДетально.AddressType = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС();
	Иначе
		НаселенныйПунктДетально.AddressType = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес();
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПеренестиЗначенияПолейАдресВПоляНовогоТипа(ТипАдреса)
	
	ИменаУровнейАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(ТипАдреса, Ложь);
	СведенияАдреса = Новый Массив;
	Для каждого ИмяУровня Из ИменаУровнейАдреса Цикл
		Если НаселенныйПунктДетально.Свойство(ИмяУровня) И ЗначениеЗаполнено(НаселенныйПунктДетально[ИмяУровня]) Тогда

			Сведения = ОписаниеСведенийАдреса();
			Сведения.Наименование  = НаселенныйПунктДетально[ИмяУровня];
			Сведения.Сокращение    = НаселенныйПунктДетально[ИмяУровня + "Type"];
			Сведения.Представление = УправлениеКонтактнойИнформациейКлиентСервер.СоединитьНаименованиеИТипАдресногоОбъекта(
				Сведения.Наименование, Сведения.Сокращение, СтрСравнить(ИмяУровня, "area") = 0);
				
			СведенияАдреса.Добавить(Сведения);
			
		КонецЕсли;
	КонецЦикла;
	
	ИменаВсехУровней = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса("Все", Ложь);
	Для каждого ИмяУровня Из ИменаВсехУровней Цикл
		НаселенныйПунктДетально[ИмяУровня]          = "";
		НаселенныйПунктДетально[ИмяУровня + "Type"] = "";
		НаселенныйПунктДетально[ИмяУровня + "Id"]   = "";
	КонецЦикла;
	
	ИменаУровнейНовогоТипа = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(НаселенныйПунктДетально.AddressType, Ложь);
	ИмяУровня = ИменаУровнейНовогоТипа.Получить(0);
	Разделитель = "";
	Для Счетчик = 0 По СведенияАдреса.Количество() - 1 Цикл
		
		Если ИменаУровнейНовогоТипа.Количество() > Счетчик + 1 Тогда
			ИмяУровня = ИменаУровнейНовогоТипа.Получить(Счетчик);
			ЗначениеСведенияАдреса = СведенияАдреса.Получить(Счетчик); // см. ОписаниеСведенийАдреса
			НаселенныйПунктДетально[ИмяУровня]          = ЗначениеСведенияАдреса.Наименование;
			НаселенныйПунктДетально[ИмяУровня + "Type"] = ЗначениеСведенияАдреса.Сокращение;
		Иначе
			НаселенныйПунктДетально[ИмяУровня] = НаселенныйПунктДетально[ИмяУровня] + Разделитель + СведенияАдреса.Получить(Счетчик).Представление;
			Разделитель = ", ";
		КонецЕсли;
		
	КонецЦикла;
	
	Если ЭтоМеждународныйАдрес(НаселенныйПунктДетально.AddressType)
		И НаселенныйПунктДетально.Свойство("Street") Тогда
		
		СписокЭлементовАдреса = Новый Массив;
		
		СписокЭлементовАдреса.Добавить(СокрЛП(НаселенныйПунктДетально["Street"] + " " + НаселенныйПунктДетально["StreetType"]));
		НаселенныйПунктДетально["StreetType"] = ""; // В иностранном адресе нет сокращений.
		
		Если НаселенныйПунктДетально.Свойство("HouseNumber") И ЗначениеЗаполнено(НаселенныйПунктДетально["HouseType"]) Тогда
			СписокЭлементовАдреса.Добавить(СокрЛП(НаселенныйПунктДетально["HouseType"] + " " + НаселенныйПунктДетально["HouseNumber"]));
			НаселенныйПунктДетально["HouseNumber"]  = "";
			НаселенныйПунктДетально["HouseType"]    = "";
			НаселенныйПунктДетально["houseId"]      = "";
			Дом                                     = "";
		КонецЕсли;
		
		Если НаселенныйПунктДетально.Свойство("buildings") И ТипЗнч(НаселенныйПунктДетально["buildings"]) = Тип("Массив") Тогда
			Для каждого СтроениеВАдресе Из НаселенныйПунктДетально["buildings"] Цикл
				СписокЭлементовАдреса.Добавить(СокрЛП(СтроениеВАдресе["Type"] + " " + СтроениеВАдресе["Number"]));
			КонецЦикла;
			НаселенныйПунктДетально["buildings"] = Новый Массив;
			Строение                             = "";
			Помещение                            = "";
		КонецЕсли;
		
		Если НаселенныйПунктДетально.Свойство("Apartments") И ТипЗнч(НаселенныйПунктДетально["Apartments"]) = Тип("Массив") Тогда
			Для каждого ПомещениеВАдресе Из НаселенныйПунктДетально["Apartments"] Цикл
				СписокЭлементовАдреса.Добавить(СокрЛП(ПомещениеВАдресе["Type"] + " " + ПомещениеВАдресе["Number"]));
			КонецЦикла;
			НаселенныйПунктДетально["Apartments"] = Новый Массив;
		КонецЕсли;
		
		НаселенныйПунктДетально["Street"] = СтрСоединить(СписокЭлементовАдреса, ", ");
		Улица = НаселенныйПунктДетально["Street"];
		
	КонецЕсли;
	
КонецПроцедуры

// Возвращаемое значение:
//  Структура:
//   * Наименование - Строка
//   * Сокращение - Строка
//   * Представление - Строка
//
&НаКлиенте
Функция ОписаниеСведенийАдреса()
	
	Сведения = Новый Структура;
	Сведения.Вставить("Наименование", "");
	Сведения.Вставить("Сокращение",  "");
	Сведения.Вставить("Представление", "");
	
	Возврат Сведения;
	
КонецФункции

&НаКлиенте
Процедура АдаптацияИдентификатораНаселенногоПункта(ИдентификаторНаселенногоПункта)
	
	Если НаселенныйПунктДетально["munDistrictId"] = ИдентификаторНаселенногоПункта 
		Или НаселенныйПунктДетально["districtId"] = ИдентификаторНаселенногоПункта Тогда
			ИдентификаторНаселенногоПункта = НаселенныйПунктДетально["areaId"];
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОтобразитьВыбранныйТипАдреса(ВыбранныйТипАдреса = Неопределено)
	
	Если УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType)
		И ПустаяСтрока(НаселенныйПунктДетально.Area) Тогда
	
			Если РаботаСАдресамиКлиентСервер.ЭтоОсновнаяСтрана(Страна) Тогда
				// Попытка восстановить адрес по полям из представления.
				НаселенныйПунктДетально = КонтактнаяИнформацияПоПредставлению(ПредставлениеАдреса, Комментарий, Истина);
			Иначе
				
				УдалитьСтрануИзПредставления();
				
				НаселенныйПунктДетально.Street = ПредставлениеАдреса;
				НаселенныйПунктДетально.AddressType = ?(СведенияОСтране.УчастникЕАЭС,
					УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС(),
					УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес());
			КонецЕсли;
			
		КонецЕсли;
		
	Если ВыбранныйТипАдреса = РаботаСАдресамиКлиентСервер.МуниципальныйАдрес() Тогда
		Если ПустаяСтрока(НаселенныйПунктДетально.munDistrict)
			И ПустаяСтрока(НаселенныйПунктДетально.settlement) Тогда
			
			УстановитьМуниципальныеСведения(НаселенныйПунктДетально);
			
		КонецЕсли;
	КонецЕсли;
	
	Если ВыбранныйТипАдреса <> Неопределено Тогда
		НаселенныйПунктДетально.AddressType = ВыбранныйТипАдреса;
	КонецЕсли;
	ОбработкаИзмененияАдреса();
	
	Если Элементы.АдресПредставлениеКомментарий.ТекущаяСтраница = Элементы.ВСвободнойФорме Тогда
		Элементы.АдресПредставлениеКомментарий.ТекущаяСтраница = Элементы.НациональныйАдрес;
	КонецЕсли;
	
	УстановитьФлагиВМенюПоТипуАдреса();
	ПоказатьПодсказкуПоТипАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура УдалитьСтрануИзПредставления()
	
	НаименованиеСтраны = ВРег(НаименованиеСтраны(Страна,
		ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).МеждународныйФорматАдреса));
	
	ПредставлениеАдреса = СокрЛП(ПредставлениеАдреса);
	Если СтрНачинаетсяС(ВРег(ПредставлениеАдреса), НаименованиеСтраны) Тогда
		Позиция = СтрДлина(НаименованиеСтраны) + 1;
		Позиция = ?(Сред(ПредставлениеАдреса, Позиция, 1) = ",", Позиция + 1, Позиция);
		ПредставлениеАдреса = СокрЛП(Сред(ПредставлениеАдреса, Позиция));
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ПоказатьСписокДомовИлиЗемельныхУчастков(ВключитьОтбор)
	
	Идентификатор = ИдентификаторАдреса(НаселенныйПунктДетально, Истина);
	
	Если ЗначениеЗаполнено(Идентификатор) Тогда
		
		ПараметрыФормы = Новый Структура();
		ПараметрыФормы.Вставить("ТипДома", ТипДома);
		ПараметрыФормы.Вставить("Номер", Дом);
		ПараметрыФормы.Вставить("Идентификатор", Идентификатор);
		ПараметрыФормы.Вставить("Строение", Строение);
		ПараметрыФормы.Вставить("ТипСтроения", ТипСтроения);
		ПараметрыФормы.Вставить("Отбор", ВключитьОтбор);
		
		ОповещениеОЗакрытие = Новый ОписаниеОповещения("ВыбранДома", ЭтотОбъект);
		ОткрытьФорму("Обработка.РасширенныйВводКонтактнойИнформации.Форма.ВыборДома", ПараметрыФормы,,,,, ОповещениеОЗакрытие, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
	Иначе
		Если ЗначениеЗаполнено(ПредставлениеАдреса) Тогда
			ТекстПредупреждения = НСтр("ru = 'Выбор из списка недоступен, т.к в адресном классификаторе отсутствует информация о нумерации домов для введенного адреса.'");
		Иначе
			ТекстПредупреждения = НСтр("ru = 'Для просмотра списка домов заполните поля адреса.'");
		КонецЕсли;
		ПоказатьПредупреждение(, ТекстПредупреждения);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ВопросОбОбновлениеАдресногоКлассификатора(Знач СообщениеОПроверкеАдреса)
	
	Кнопки = Новый СписокЗначений();
	Кнопки.Добавить("Закрыть", НСтр("ru = 'Закрыть'"));
	Кнопки.Добавить("ОбновитьКлассификатор", НСтр("ru = 'Обновить классификатор'"));
	Оповещение = Новый ОписаниеОповещения("ПослеВопросОбОбновление", ЭтотОбъект);
	ПоказатьВопрос(Оповещение, СообщениеОПроверкеАдреса, Кнопки);
	
КонецПроцедуры

&НаКлиенте
Процедура ВыбранДома(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат <> Неопределено Тогда
		ЗаполнитьПоляДомовСтроенийЗемельныхУчастков(Результат);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура УстановитьПиктограммуКомментария()
	Элементы.СтраницаКомментарий.Картинка = ОбщегоНазначенияКлиентСервер.КартинкаКомментария(Комментарий);
КонецПроцедуры

// Возвращаемое значение:
//   Структура:
//     * ВидКонтактнойИнформации - см. УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации
//     * НаселенныйПунктДетально - Структура
//     * ОсновнаяСтрана - СправочникСсылка.СтраныМира
//     * Страна - СправочникСсылка.СтраныМира
//     * ИсключатьГородИзМуниципальногоАдреса - Булево
//
&НаКлиенте
Функция ОписаниеКонтекста()
	
	Контекст = Новый Структура;
	Контекст.Вставить("ВидКонтактнойИнформации", Новый Структура);
	Контекст.Вставить("НаселенныйПунктДетально", Новый Структура);
	Контекст.Вставить("ОсновнаяСтрана", Неопределено);
	Контекст.Вставить("Страна", Неопределено);
	Контекст.Вставить("ИсключатьГородИзМуниципальногоАдреса", Ложь);
	
	ЗаполнитьЗначенияСвойств(Контекст, ЭтотОбъект);
	
	Возврат Контекст;
	
КонецФункции

&НаКлиенте
Процедура ПодтвердитьИЗакрыть(Результат = Неопределено, ДополнительныеПараметры = Неопределено) Экспорт
	
	Если Модифицированность Тогда // При немодифицированности работает как "отмена".
		
		Контекст = ОписаниеКонтекста();
		
		Результат = РезультатВыбора(Контекст, ВозвращатьСписокЗначений);
		
		// Флаги вида были прочитаны заново.
		ВидКонтактнойИнформации = Контекст.ВидКонтактнойИнформации;
		
		Если (ВидКонтактнойИнформации.ПроверятьКорректность	И Не РазрешитьВводАдресаВСвободнойФорме
			Или ВидКонтактнойИнформации.МеждународныйФорматАдреса)
			И Результат.ОшибкиЗаполнения.Количество() > 0 Тогда
			
			СообщитьОбОшибкахЗаполнения(Результат.ОшибкиЗаполнения, Ложь);
			Возврат;
			
		КонецЕсли;
		
		Результат = Результат.ДанныеВыбора;
		Если ВидКонтактнойИнформации.ХранитьИсториюИзменений Тогда
			ОбработатьКонтактнуюИнформациюСИсторией(Результат);
		КонецЕсли;
		
		Если ТипЗнч(Результат) = Тип("Структура") Тогда
			Результат.Вставить("КонтактнаяИнформацияОписаниеДополнительныхРеквизитов", КонтактнаяИнформацияОписаниеДополнительныхРеквизитов);
		КонецЕсли;
		
		СброситьМодифицированностьПриВыборе();
#Если ВебКлиент Тогда
		ФлагЗакрытия = ЗакрыватьПриВыборе;
		ЗакрыватьПриВыборе = Ложь;
		ОповеститьОВыборе(Результат);
		ЗакрыватьПриВыборе = ФлагЗакрытия;
#Иначе
		ОповеститьОВыборе(Результат);
#КонецЕсли
		СохранитьСостояниеФормы();
		
	Иначе
		Результат = Неопределено;
	КонецЕсли;
	
	Если (МодальныйРежим Или ЗакрыватьПриВыборе) И Открыта() Тогда
		СброситьМодифицированностьПриВыборе();
		СохранитьСостояниеФормы();
		Закрыть(Результат);
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура ОбработатьКонтактнуюИнформациюСИсторией(Результат)
	
	Результат.Вставить("ДействуетС", ?(ВводНовогоАдреса, АдресНаДату, АдресДействуетС));
	ИмяРеквизита = "";
	Отбор = Новый Структура("Вид", Результат.Вид);
	
	СтрокаДействующегоАдреса = Неопределено;
	ДатаБылаИзменена         = Истина;
	ТекущаяДатаАдреса        = ОбщегоНазначенияКлиент.ДатаСеанса();
	Дельта                   = АдресНаДату - ТекущаяДатаАдреса;
	МинимальнаяДельта        = ?(Дельта > 0, Дельта, -Дельта);
	НайденныеСтроки          = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
	Для Каждого НайденнаяСтрока Из НайденныеСтроки Цикл
		Если ЗначениеЗаполнено(НайденнаяСтрока.ИмяРеквизита) Тогда
			ИмяРеквизита = НайденнаяСтрока.ИмяРеквизита;
		КонецЕсли;
		Если НайденнаяСтрока.ДействуетС = АдресНаДату Тогда
			ДатаБылаИзменена = Ложь;
			СтрокаДействующегоАдреса = НайденнаяСтрока;
			Прервать;
		КонецЕсли;
		
		Дельта = ТекущаяДатаАдреса - НайденнаяСтрока.ДействуетС;
		Дельта = ?(Дельта > 0, Дельта, -Дельта);
		Если Дельта <= МинимальнаяДельта Тогда
			МинимальнаяДельта = Дельта;
			СтрокаДействующегоАдреса = НайденнаяСтрока;
		КонецЕсли;
	КонецЦикла;
	
	Если СтрокаДействующегоАдреса <> Неопределено Тогда
		ДанныеБылиИзменены = ДанныеБылиИзменены(Результат.Значение, СтрокаДействующегоАдреса.Значение);
	Иначе
		ДанныеБылиИзменены = Истина;
	КонецЕсли;
	
	Если ДатаБылаИзменена Тогда
		
		Отбор = Новый Структура("ДействуетС, Вид", АдресДействуетС, Результат.Вид);
		СтрокиСАдресом = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
		
		Если ДанныеБылиИзменены Тогда
				НоваяКонтактнаяИнформация = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяКонтактнаяИнформация, Результат);
				НоваяКонтактнаяИнформация.ЗначенияПолей           = Результат.КонтактнаяИнформация;
				НоваяКонтактнаяИнформация.Значение                = Результат.Значение;
				НоваяКонтактнаяИнформация.ДействуетС              = АдресНаДату;
				НоваяКонтактнаяИнформация.ХранитьИсториюИзменений = Истина;
				Если СтрокаДействующегоАдреса = Неопределено Тогда
					Отбор = Новый Структура("ЭтоИсторическаяКонтактнаяИнформация, Вид", Ложь, Результат.Вид);
					НайденныеСтроки = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
					Для каждого НайденнаяСтрока Из НайденныеСтроки Цикл
						НайденнаяСтрока.ЭтоИсторическаяКонтактнаяИнформация = Истина;
						НайденнаяСтрока.ИмяРеквизита = "";
					КонецЦикла;
					НоваяКонтактнаяИнформация.ИмяРеквизита = ИмяРеквизита;
					НоваяКонтактнаяИнформация.ЭтоИсторическаяКонтактнаяИнформация = Ложь;
				Иначе
					НоваяКонтактнаяИнформация.ЭтоИсторическаяКонтактнаяИнформация = Истина;
					Результат.Представление                = СтрокаДействующегоАдреса.Представление;
					Результат.КонтактнаяИнформация         = СтрокаДействующегоАдреса.ЗначенияПолей;
					Результат.Значение                     = СтрокаДействующегоАдреса.Значение;
				КонецЕсли;
		ИначеЕсли СтрокаДействующегоАдреса <> Неопределено
				И СтрСравнить(Результат.Комментарий, СтрокаДействующегоАдреса.Комментарий) <> 0
				И СтрокиСАдресом.Количество() > 0 Тогда
					// Поменяли только комментарий.
					СтрокиСАдресом[0].Комментарий = Результат.Комментарий;
		КонецЕсли;
	Иначе
		Если ДанныеБылиИзменены Тогда
			ЗаполнитьЗначенияСвойств(СтрокаДействующегоАдреса, Результат);
			СтрокаДействующегоАдреса.ЗначенияПолей                       = Результат.КонтактнаяИнформация;
			СтрокаДействующегоАдреса.Значение                            = Результат.Значение;
			СтрокаДействующегоАдреса.ИмяРеквизита                        = ИмяРеквизита;
			СтрокаДействующегоАдреса.ЭтоИсторическаяКонтактнаяИнформация = Ложь;
		КонецЕсли;
	КонецЕсли;

КонецПроцедуры

&НаСервереБезКонтекста
Функция ДанныеБылиИзменены(ЗначениеПолейДо, ЗначениеПолейПосле)
	
	Если СтрСравнить(ЗначениеПолейПосле, ЗначениеПолейДо) = 0 Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ЗначениеПолейДо)И ЗначениеЗаполнено(ЗначениеПолейПосле) Тогда
		
		ЗначенияДо    = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(ЗначениеПолейДо, Перечисления.ТипыКонтактнойИнформации.Адрес);
		ЗначенияПосле = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(ЗначениеПолейПосле, Перечисления.ТипыКонтактнойИнформации.Адрес);
		
		Если СтрСравнить(ЗначенияДо.value, ЗначенияПосле.value) <> 0
			Или СтрСравнить(ЗначенияДо.country, ЗначенияПосле.country) <> 0
			Или СтрСравнить(ЗначенияДо.comment, ЗначенияПосле.comment) <> 0
			Или СтрСравнить(ЗначенияДо.oktmo, ЗначенияПосле.oktmo) <> 0 Тогда
				Возврат Истина;
		КонецЕсли;
		
		Возврат Ложь;
		
	КонецЕсли;
	
	Возврат Истина; // Один из вариантов пустой, другой заполнен.
	
КонецФункции

&НаКлиенте
Процедура ПослеЗакрытияФормыИстории(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	ВводНовогоАдреса = ?(Результат.Свойство("ВводНовогоАдреса"), Результат.ВводНовогоАдреса, Ложь);
	Если ВводНовогоАдреса Тогда
		АдресДействуетС = АдресНаДату;
		АдресНаДату     = Результат.ТекущийАдрес;
		Страна          = ОсновнаяСтрана;
		ТипАдреса       = НаселенныйПунктДетально.addressType;
		НаселенныйПунктДетально = РаботаСАдресамиКлиентСервер.ОписаниеНовойКонтактнойИнформации(ПредопределенноеЗначение("Перечисление.ТипыКонтактнойИнформации.Адрес"));
		НаселенныйПунктДетально.Country     = Строка(Страна);
		НаселенныйПунктДетально.addressType = ТипАдреса;
		ОбработкаИзмененияАдреса();
	Иначе
		Отбор = Новый Структура("Вид", ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).Ссылка);
		НайденныеСтроки = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
		
		ИмяРеквизита = "";
		Для Каждого СтрокаКонтактнойИнформации Из НайденныеСтроки Цикл
			Если НЕ СтрокаКонтактнойИнформации.ЭтоИсторическаяКонтактнаяИнформация Тогда
				ИмяРеквизита = СтрокаКонтактнойИнформации.ИмяРеквизита;
			КонецЕсли;
			КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.Удалить(СтрокаКонтактнойИнформации);
		КонецЦикла;
		
		Для Каждого СтрокаКонтактнойИнформации Из Результат.История Цикл
			ДанныеСтроки = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.Добавить();
			ЗаполнитьЗначенияСвойств(ДанныеСтроки, СтрокаКонтактнойИнформации);
			Если НЕ СтрокаКонтактнойИнформации.ЭтоИсторическаяКонтактнаяИнформация Тогда
				ДанныеСтроки.ИмяРеквизита = ИмяРеквизита;
			КонецЕсли;
			Если НачалоДня(Результат.ТекущийАдрес) = НачалоДня(СтрокаКонтактнойИнформации.ДействуетС) Тогда
				АдресНаДату = Результат.ТекущийАдрес;
				НаселенныйПунктДетально = СтрокаJSONВСтруктуру(СтрокаКонтактнойИнформации.Значение);
				Комментарий = НаселенныйПунктДетально.comment;
				ОбработкаИзмененияАдреса();
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ОтобразитьИнформациюОДатахДействияАдреса(АдресНаДату);
	
	Если НЕ Модифицированность Тогда
		Модифицированность = Результат.Модифицированность;
	КонецЕсли;
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция СтрокаJSONВСтруктуру(Значение)
	Возврат УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(Значение, Перечисления.ТипыКонтактнойИнформации.Адрес);
КонецФункции

&НаКлиенте
Процедура СохранитьСостояниеФормы()
	УстановитьКлючИспользованияФормы();
	СохраняемыеВНастройкахДанныеМодифицированы = Истина;
КонецПроцедуры

&НаКлиенте
Процедура СброситьМодифицированностьПриВыборе()
	Модифицированность = Ложь;
	КопияКомментария   = Комментарий;
КонецПроцедуры

// Параметры:
//  Контекст - см. ОписаниеКонтекста
//   
//  ВозвращатьСписокЗначений - Булево
// Возвращаемое значение:
//  Структура:
//   * ДанныеВыбора - Структура:
//     ** Представление - Строка
//     ** КонтактнаяИнформация - Строка
//     ** Значение - Строка
//     ** Комментарий - Строка
//     ** ВведеноВСвободнойФорме - Булево
//     ** ВВидеГиперссылки - Булево
//     ** Вид - СправочникСсылка.ВидыКонтактнойИнформации
//     ** Тип - ПеречислениеСсылка.ТипыКонтактнойИнформации
//   * ОшибкиЗаполнения - Массив из Строка
//
&НаСервереБезКонтекста
Функция РезультатВыбора(Контекст, ВозвращатьСписокЗначений = Ложь)
	
	// Обновляем некоторые флаги
	ВидКИ = Контекст.ВидКонтактнойИнформации; // см. УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации
	ЗначениеФлагов = УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации(ВидКИ.Ссылка);
	
	ВидКИ.ТолькоНациональныйАдрес = ЗначениеФлагов.ТолькоНациональныйАдрес;
	ВидКИ.ПроверятьКорректность   = ЗначениеФлагов.ПроверятьКорректность;
	
	НаселенныйПунктДетально = Контекст.НаселенныйПунктДетально;
	Результат      = Новый Структура("ДанныеВыбора, ОшибкиЗаполнения");
	
	НаселенныйПунктДетально.Value = РаботаСАдресамиКлиентСервер.ПредставлениеАдреса(НаселенныйПунктДетально, ВидКИ.ВключатьСтрануВПредставление);
	
	Если ВозвращатьСписокЗначений Тогда
		ДанныеВыбора = Обработки.РасширенныйВводКонтактнойИнформации.КонтактнаяИнформацияВСтаруюСтруктуру(НаселенныйПунктДетально);
	ИначеЕсли Контекст.Страна = Контекст.ОсновнаяСтрана И ПустаяСтрока(НаселенныйПунктДетально.Value) Тогда
		ДанныеВыбора = "";
	Иначе
		ДанныеВыбора = НаселенныйПунктДетально;
	КонецЕсли;
	
	Если ТипЗнч(ДанныеВыбора) = Тип("Структура") Тогда
		Если ПустаяСтрока(ДанныеВыбора.countryCode) Тогда
			СведенияОСтране = УправлениеКонтактнойИнформацией.ДанныеСтраныМира(Неопределено, ДанныеВыбора.Country);
			Если СведенияОСтране <> Неопределено Тогда
				ДанныеВыбора.countryCode = СведенияОСтране.Код;
			КонецЕсли;
		КонецЕсли;
		
		Значение = УправлениеКонтактнойИнформациейСлужебный.СтруктураВСтрокуJSON(ДанныеВыбора);
		КонтактнаяИнформация = УправлениеКонтактнойИнформациейЛокализация.КонтактнаяИнформацияИзJSONВXML(ДанныеВыбора, Перечисления.ТипыКонтактнойИнформации.Адрес);
	Иначе
		Значение             = "";
		КонтактнаяИнформация = "";
	КонецЕсли;
	
	Результат.ДанныеВыбора = Новый Структура;
	Результат.ДанныеВыбора.Вставить("КонтактнаяИнформация", КонтактнаяИнформация);
	Результат.ДанныеВыбора.Вставить("Значение", Значение);
	Результат.ДанныеВыбора.Вставить("Представление", НаселенныйПунктДетально.Value);
	Результат.ДанныеВыбора.Вставить("Комментарий", НаселенныйПунктДетально.Comment);
	Результат.ДанныеВыбора.Вставить("ВведеноВСвободнойФорме",
		УправлениеКонтактнойИнформациейСлужебный.АдресВведенВСвободнойФорме(НаселенныйПунктДетально));
		
	// ошибки заполнения
	Результат.ОшибкиЗаполнения = Новый Массив;
	ПроверятьКорректность = ВидКИ.ПроверятьКорректность Или ВидКИ.МеждународныйФорматАдреса;
	Если ПроверятьКорректность И ЗначениеЗаполнено(Значение) Тогда
		Результат.ОшибкиЗаполнения = Обработки.РасширенныйВводКонтактнойИнформации.ОшибкиЗаполненияАдреса(
			Значение, ВидКИ);
	КонецЕсли;
		
	Результат.ДанныеВыбора.Вставить("ВВидеГиперссылки", Контекст.ВидКонтактнойИнформации.ВидРедактирования = "Диалог");
	
	// Подавляем перенос строк в возвращаемом отдельно представлении.
	Результат.ДанныеВыбора.Представление = СокрЛП(СтрЗаменить(Результат.ДанныеВыбора.Представление, Символы.ПС, " "));
	Результат.ДанныеВыбора.Вставить("Вид",ВидКИ.Ссылка);
	Результат.ДанныеВыбора.Вставить("Тип", Перечисления.ТипыКонтактнойИнформации.Адрес);
	
	Возврат Результат;
КонецФункции

&НаСервереБезКонтекста
Функция СписокОшибокЗаполнения(Адрес, ВидКонтактнойИнформации, ПредупреждатьОбОтсутствии, ТребуетсяОбновление = Ложь)
	
	Результат = Обработки.РасширенныйВводКонтактнойИнформации.ОшибкиЗаполненияАдреса(Адрес, ВидКонтактнойИнформации);
	ОпределитьНеобходимостьОбновленияКлассификатора(Адрес, ТребуетсяОбновление);
	
	Возврат Результат;
КонецФункции

&НаСервереБезКонтекста
Процедура ОпределитьНеобходимостьОбновленияКлассификатора(Знач НаселенныйПунктДетально, ТребуетсяОбновление)
	
	// проверка источника
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		МодульАдресныйКлассификаторСлужебный = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификаторСлужебный");
		ИнформацияОбОбновление = МодульАдресныйКлассификаторСлужебный.ОписаниеПоследнейЗагрузки(НаселенныйПунктДетально.AreaID);
		ТребуетсяОбновление = ИнформацияОбОбновление.НеобходимоОбновление;
	КонецЕсли;

КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция НаименованиеРегиона(НаселенныйПункт)
	
	Возврат СокрЛП(НаселенныйПункт.area + " " + НаселенныйПункт.areaType);
	
КонецФункции

&НаСервереБезКонтекста
Функция АдресныеСведенияКлассификатораЗагружены(НаименованиеРегиона)
	
	Результат = Новый Структура;
	Результат.Вставить("АдресныйКлассификаторДоступен", Ложь);
	Результат.Вставить("РегионЗагружен",                Ложь);
	Результат.Вставить("СведенияУстарели",              Ложь);
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		
		Результат.АдресныйКлассификаторДоступен = Истина;
		
		МодульАдресныйКлассификатор = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификатор");
		КодРегиона = МодульАдресныйКлассификатор.КодРегионаПоНаименованию(НаименованиеРегиона);
		
		СведенияОАдресномКлассификаторе = УправлениеКонтактнойИнформациейСлужебныйПовтИсп.СведенияОДоступностиАдресногоКлассификатора();
		СведенияОРегиона = СведенияОАдресномКлассификаторе.Получить(КодРегиона);
		Если ТипЗнч(СведенияОРегиона) = Тип("Структура") Тогда
			Результат.РегионЗагружен = СведенияОРегиона.ИспользоватьЗагруженные;
			ОписаниеДаты = Новый ОписаниеТипов("Дата");
			ДатаЗагрузки = ОписаниеДаты.ПривестиЗначение(СведенияОРегиона.ДатаЗагрузки);
			Если ТекущаяДатаСеанса() - ДатаЗагрузки > 2592000 Тогда
				Результат.СведенияУстарели = Истина; // Данным более 30 дней.
			КонецЕсли;
		Иначе
			Результат.РегионЗагружен = СведенияОАдресномКлассификаторе.Получить("ИспользоватьЗагруженные");
		КонецЕсли;
		
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

&НаСервереБезКонтекста
Функция ЗаполнитьСписокКонтактнойИнформации(ВидКонтактнойИнформации, КонтактнаяИнформацияОписаниеДополнительныхРеквизитов)

	Отбор = Новый Структура("Вид", ВидКонтактнойИнформации);
	НайденныеСтроки = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
	
	СписокКонтактнойИнформации = Новый Массив;
	Для каждого СтрокаКонтактнойИнформации Из НайденныеСтроки Цикл
		КонтактнаяИнформация = НовыйСписокКонтактнойИнформации();
		ЗаполнитьЗначенияСвойств(КонтактнаяИнформация, СтрокаКонтактнойИнформации);
		СписокКонтактнойИнформации.Добавить(КонтактнаяИнформация);
	КонецЦикла;
	
	Возврат СписокКонтактнойИнформации;
КонецФункции

// Возвращаемое значение:
//  Структура:
//   * Представление - Строка
//   * Значение - Строка
//   * ЗначенияПолей - Строка
//   * ДействуетС - Неопределено, Дата
//   * Комментарий - Строка
//
&НаСервереБезКонтекста
Функция НовыйСписокКонтактнойИнформации()
	
	Результат = Новый Структура;
	Результат.Вставить("Представление", ""); 
	Результат.Вставить("Значение",      "");
	Результат.Вставить("ЗначенияПолей", "");
	Результат.Вставить("ДействуетС",    Неопределено); 
	Результат.Вставить("Комментарий",   "");
	
	Возврат Результат;
	
КонецФункции

&НаКлиенте
Процедура ПослеЗагрузкиАдресногоКлассификатора(Результат, ДополнительныеПараметры) Экспорт
	Если ТипЗнч(НаселенныйПунктДетально) = Тип("Структура") И НаселенныйПунктДетально.Свойство("areaId") Тогда
		СообщениеОНеобходимостиОбновленияКлассификатора(НаселенныйПунктДетально.areaId);
	КонецЕсли;
КонецПроцедуры

&НаСервере
Процедура СообщениеОНеобходимостиОбновленияКлассификатора(Идентификатор = Неопределено)
	
	Элементы.АдресныйКлассификаторУстарел.Видимость = Ложь;
	Если НЕ ВебСервисИспользуется И ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		МодульАдресныйКлассификаторСлужебный = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификаторСлужебный");
		ИнформацияОбОбновление = МодульАдресныйКлассификаторСлужебный.ОписаниеПоследнейЗагрузки(Идентификатор);
		Элементы.АдресныйКлассификаторУстарел.Видимость = ИнформацияОбОбновление.НеобходимоОбновление;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОтобразитьПоляПоТипуАдреса()
	
	Если УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType) Тогда
		ПоказатьАдресВСвободнойФорме();
	КонецЕсли;
	
	ЭтоНациональныйАдрес = (Страна = ОсновнаяСтрана И Не МеждународныйФорматАдреса);
	ОпределитьДоступностьАвтоПодборАдреса();
	
	Если МеждународныйФорматАдреса Тогда
		НаселенныйПунктДетально.Country = ?(ЗначениеЗаполнено(СведенияОСтране.МеждународноеНаименование),
			СведенияОСтране.МеждународноеНаименование, ДанныеСтраныМира(СведенияОСтране).Наименование);
	Иначе
		НаселенныйПунктДетально.Country = ДанныеСтраныМира(СведенияОСтране).Наименование;
	КонецЕсли;
	
	Если ЭтоНациональныйАдрес Тогда
		
		Если ПустаяСтрока(НаселенныйПунктДетально.AddressType) Тогда
			НаселенныйПунктДетально.AddressType = РаботаСАдресамиКлиентСервер.МуниципальныйАдрес();
		КонецЕсли;
		
		ЭтоЗемельныйУчасток = ?(ЭтоЗемельныйУчасток(ТипДома), Истина, Ложь);
		
		Элементы.Улица.Заголовок                     = НСтр("ru = 'Улица'");
		Элементы.ОКТМО.Видимость                     = ВидКонтактнойИнформации.УказыватьОКТМО;
		ВебСервисИспользуется                        = ВебКлассификаторДоступен;
		АвтоподборДоступен                           = ИспользуетсяАдресныйКлассификатор И (ВебКлассификаторДоступен Или ЕстьЗагруженныйКлассификатор);
		ВидимостьСтроений                            = Истина;
		Элементы.ГруппаДобавлениеСтроения.Видимость  = Истина;
		Элементы.ГруппаДобавлениеПомещения.Видимость = Истина;
		Элементы.Дом.КнопкаВыбора                    = АвтоподборДоступен;
		Элементы.Улица.КнопкаВыбора                  = АвтоподборДоступен;
		Элементы.НаселенныйПункт.КнопкаВыбора        = Истина;
		Элементы.Строение.КнопкаВыбора               = Ложь;
		Элементы.Строение.Доступность                = Не ЭтоЗемельныйУчасток;
		Элементы.ТипСтроения.Доступность             = Не ЭтоЗемельныйУчасток;
		Элементы.НаселенныйПункт.ПодсказкаВвода      = НСтр("ru = 'Введите первые буквы названия населенного пункта'");
		Элементы.Улица.ПодсказкаВвода                = НСтр("ru = 'Введите первые буквы названия улицы'");
		
	Иначе
		
		Элементы.ГруппаДобавлениеСтроения.Видимость  = Ложь;
		Элементы.ГруппаДобавлениеПомещения.Видимость = Ложь;
		Если СведенияОСтране.УчастникЕАЭС И Не МеждународныйФорматАдреса Тогда
			Элементы.Улица.Заголовок              = НСтр("ru = 'Улица'");
			Элементы.НаселенныйПункт.КнопкаВыбора = Истина;
			ВидимостьСтроений                     = Истина;
			Элементы.Дом.КнопкаВыбора             = Ложь;
			Элементы.Строение.КнопкаВыбора        = Ложь;
			
		Иначе
			Элементы.Улица.Заголовок              = НСтр("ru = 'Адрес'");
			Элементы.НаселенныйПункт.КнопкаВыбора = Ложь;
			Элементы.Улица.КнопкаВыбора           = Ложь;
			ВидимостьСтроений                     = Ложь;
		КонецЕсли;
		
		Элементы.ОКТМО.Видимость                       = Ложь;
		Элементы.ПроверитьЗаполнениеАдреса.Доступность = Ложь;
		ВебСервисИспользуется                          = Ложь;
		АвтоподборДоступен                             = Ложь;
		Элементы.НаселенныйПункт.ПодсказкаВвода        = "";
		Элементы.Улица.ПодсказкаВвода                  = "";
		
	КонецЕсли;
	
	// Проверять, вводить в свободной форме и искать по индексу можем только российские адреса.
	Элементы.Улица.МногострочныйРежим                          = НЕ ЭтоНациональныйАдрес;
	Элементы.ГруппаСтроенияИИнформация.Видимость               = ВидимостьСтроений;
	Элементы.ПроверитьЗаполнениеАдреса.Доступность             = ЭтоНациональныйАдрес И АвтоподборДоступен;
	Элементы.ЗаполнитьПоПочтовомуИндексу.Доступность           = ЭтоНациональныйАдрес;
	Элементы.МуниципальноеДеление.Доступность                  = ЭтоНациональныйАдрес;
	Элементы.АдминистративноТерриториальноеДеление.Доступность = ЭтоНациональныйАдрес;
	
	Если ВидКонтактнойИнформации.ВключатьСтрануВПредставление Тогда
		ОбновитьПредставлениеАдреса();
	КонецЕсли;
	
	УстановитьФлагиВМенюПоТипуАдреса();
	ПоказатьПодсказкуПоТипАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура ОпределитьДоступностьАвтоПодборАдреса()
	
	Если Не РаботаСАдресамиКлиентСервер.ЭтоОсновнаяСтрана(Страна) Тогда
		АвтоподборДоступен = Ложь;
		Возврат;
	КонецЕсли;
	
	АвтоподборДоступен = ВебКлассификаторДоступен Или ЕстьЗагруженныйКлассификатор;
	
КонецПроцедуры

&НаСервере
Процедура ОпределитьОтображениеЭлементовНаФорме(ТолькоПросмотр)
	// Разовые настройки отображения формы.
	
	Если Не ЕстьЗагруженныйКлассификатор Тогда
		Элементы.ЗаполнитьПоПочтовомуИндексу.Видимость            = Ложь;
		Элементы.Улица.КнопкаВыбора                               = Ложь;
		Элементы.Дом.КнопкаВыбора                                 = Ложь;
		Элементы.Строение.КнопкаВыбора                            = Ложь;
		Элементы.НаселенныйПункт.ПодсказкаВвода                   = НСтр("ru = 'Введите название населенного пункта'");
		Элементы.Улица.ПодсказкаВвода                             = НСтр("ru = 'Введите название улицы'");
	КонецЕсли;
	
	Если ВебКлассификаторДоступен Или МеждународныйФорматАдреса Тогда
		
		Элементы.ГруппаИнформация.Видимость = Ложь;
		
	Иначе
		
		СведенияОЗагрузке = АдресныеСведенияКлассификатораЗагружены(НаименованиеРегиона(НаселенныйПунктДетально));
		Если СведенияОЗагрузке.АдресныйКлассификаторДоступен Тогда
			Если Не СведенияОЗагрузке.РегионЗагружен Тогда
				Элементы.ГруппаИнформация.Видимость             = Истина;
			Иначе
				Элементы.ГруппаИнформация.Видимость             = Ложь;
				Элементы.АдресныйКлассификаторУстарел.Видимость = СведенияОЗагрузке.СведенияУстарели;
			КонецЕсли;
		КонецЕсли;
		
	КонецЕсли;
	
	Если ТолькоПросмотр Тогда
		Элементы.ГруппаКомандаДобавить.Видимость = Ложь;
		Элементы.ДобавитьКомментарий.Доступность = Ложь;
		Элементы.ФормаОчиститьАдрес.Доступность  = Ложь;
		Элементы.АдресНаДату.Доступность         = Ложь;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура УстановитьСписокВыбораЭлемента(ЭлементВид, ЭлементЗначение, Данные)
	
	ЭлементЗначение.КнопкаВыпадающегоСписка = Данные.МожноПодбиратьЗначения;
	
	СписокТипов = Данные.ВариантыТипа;
	ЭлементВид.КнопкаВыпадающегоСписка = СписокТипов.Количество() > 0;
	Если ЭлементВид.КнопкаВыпадающегоСписка Тогда
		Для Каждого НаименованиеТипа Из СписокТипов Цикл
			Если ЭлементВид.СписокВыбора.НайтиПоЗначению(НаименованиеТипа) = Неопределено Тогда
				ЭлементВид.СписокВыбора.Добавить(НаименованиеТипа);
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура УстановитьЗначениеРеквизитовПоКонтактнойИнформации(ДанныеАдреса)
	
	// Общие реквизиты
	ПредставлениеАдреса = ДанныеАдреса.Value;
	Если ДанныеАдреса.Свойство("Comment") Тогда
		Комментарий         = ДанныеАдреса.Comment;
	КонецЕсли;
	
	СсылкаНаОсновнуюСтрану = РаботаСАдресамиКлиентСервер.ОсновнаяСтрана();
	ДанныеСтраны = Неопределено;
	Если ДанныеАдреса.Свойство("Country") И ЗначениеЗаполнено(ДанныеАдреса.Country) Тогда
		ДанныеСтраны = Справочники.СтраныМира.ДанныеСтраныМира(, СокрЛП(ДанныеАдреса.Country));
	КонецЕсли;
	
	Если ДанныеСтраны = Неопределено Тогда
		// Не нашли ни в справочнике, ни в классификаторе.
		Страна    = СсылкаНаОсновнуюСтрану;
		КодСтраны = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СсылкаНаОсновнуюСтрану, "Код");
	Иначе
		Страна    = ДанныеСтраны.Ссылка;
		КодСтраны = ДанныеСтраны.Код;
	КонецЕсли;
	
	СведенияОСтране = СведенияОСтране(Страна);
	
	Если УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(ДанныеАдреса.AddressType) Тогда
		РазрешитьВводАдресаВСвободнойФорме = Истина;
	КонецЕсли;
	
	УстановитьЗначенияНациональныхРеквизитовКонтактнойИнформации(ДанныеАдреса);
	
КонецПроцедуры

&НаСервере
Процедура УстановитьЗначенияНациональныхРеквизитовКонтактнойИнформации(ДанныеАдреса)

	// Индекс просто ставим
	Если ДанныеАдреса.Свойство("ZIPCode") Тогда
		Индекс = Формат(ДанныеАдреса.ZIPCode, "ЧГ=");
	КонецЕсли;
	
	// Индекс просто ставим
	Если ДанныеАдреса.Свойство("OKTMO") Тогда
		ОКТМО = Формат(ДанныеАдреса.OKTMO, "ЧГ=");
	КонецЕсли;
	
	// Синтетический "Населенный пункт" получаем как представление.
	НаселенныйПункт = Обработки.РасширенныйВводКонтактнойИнформации.ПредставлениеНаселенногоПункта(ДанныеАдреса);
	Если ЗначениеЗаполнено(ДанныеАдреса.Street) Тогда
		Улица = УправлениеКонтактнойИнформациейКлиентСервер.СоединитьНаименованиеИТипАдресногоОбъекта(ДанныеАдреса.Street, 
				ДанныеАдреса.StreetType);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ДанныеАдреса.HouseType) Тогда
		ТипДома = ДанныеАдреса.HouseType;
		Если ДанныеАдреса.Свойство("HouseNumber") Тогда
			Дом = ДанныеАдреса.HouseNumber;
		ИначеЕсли ДанныеАдреса.Свойство("House") Тогда
			Дом = ДанныеАдреса.House;
		КонецЕсли;
	ИначеЕсли ЗначениеЗаполнено(ДанныеАдреса.stead) Тогда
		ТипДома = РаботаСАдресамиКлиентСервер.НаименованиеЗемельногоУчастка();
		Дом = ДанныеАдреса.stead;
	КонецЕсли;
	
	ЗаполняемПервоеЗдание = Истина;
	Если ДанныеАдреса.Свойство("buildings") И  ТипЗнч(ДанныеАдреса.buildings) = Тип("Массив") Тогда
		Для каждого ОписаниеЗдания Из ДанныеАдреса.buildings Цикл
			Если ЗаполняемПервоеЗдание Тогда
				ТипСтроения = ОписаниеЗдания.Type;
				Строение    = ОписаниеЗдания.Number;
				ЗаполняемПервоеЗдание = Ложь;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ЗаполняемПервоеПомещение = Истина;
	Если ДанныеАдреса.Свойство("Apartments") И  ТипЗнч(ДанныеАдреса.Apartments) = Тип("Массив") Тогда
		Для каждого ОписаниеСтроения Из ДанныеАдреса.Apartments Цикл
			Если ЗаполняемПервоеПомещение Тогда
				ТипПомещения    = ОписаниеСтроения.Type;
				Помещение       = ОписаниеСтроения.Number;
				ЗаполняемПервоеПомещение = Ложь;
			КонецЕсли;
		КонецЦикла;
	КонецЕсли;
	
	ОтобразитьДополнительныеЗдания(НаселенныйПунктДетально);
	
КонецПроцедуры

&НаСервере
Функция ДобавитьПолеСтроенияИлиПомещения(Идентификатор, Тип, Значение)
	
	Если Тип = "Помещение" Тогда
		
		НоваяГруппа = Элементы.Добавить("ГруппаПомещение" + Идентификатор, Тип("ГруппаФормы"), Элементы.ГруппаПомещенияДополнительно);
		ЗаполнитьЗначенияСвойств(НоваяГруппа, Элементы.ГруппаПомещенияОсновная,, "ПутьКДаннымЗаголовка");
		
		НовыйТип = Элементы.Добавить("ТипПомещения" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
		ЗаполнитьЗначенияСвойств(НовыйТип, Элементы.ТипПомещения,, "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
		НовыйТип.СписокВыбора.ЗагрузитьЗначения(Элементы.ТипПомещения.СписокВыбора.ВыгрузитьЗначения());
		НовыйТип.УстановитьДействие("ПриИзменении", "Подключаемый_ТипПомещенияПриИзменении");
		Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
				НовыйТип.КнопкаВыбора = Истина;
				НовыйТип.ОтображениеКнопкиВыбора = ОтображениеКнопкиВыбора.Авто;
		КонецЕсли;
		
		НовыйЭлемент = Элементы.Добавить("Помещение" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
		ЗаполнитьЗначенияСвойств(НовыйЭлемент, Элементы.Помещение,, "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
		НовыйЭлемент.СписокВыбора.ЗагрузитьЗначения(Элементы.Помещение.СписокВыбора.ВыгрузитьЗначения());
		НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПомещениеПриИзменении");
		
	Иначе
		
		НоваяГруппа = Элементы.Добавить("ГруппаСтроение" + Идентификатор, Тип("ГруппаФормы"), Элементы.ГруппаСтроенияДополнительно);
		ЗаполнитьЗначенияСвойств(НоваяГруппа, Элементы.ГруппаСтроенияОсновная,, "ПутьКДаннымЗаголовка");
		
		НовыйТип = Элементы.Добавить("ТипСтроения" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
		ЗаполнитьЗначенияСвойств(НовыйТип, Элементы.ТипСтроения,, "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
		НовыйТип.СписокВыбора.ЗагрузитьЗначения(Элементы.ТипСтроения.СписокВыбора.ВыгрузитьЗначения());
		НовыйТип.УстановитьДействие("ПриИзменении", "Подключаемый_ТипСтроенияПриИзменении");
		Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
			НовыйТип.КнопкаВыбора = Истина;
			НовыйТип.ОтображениеКнопкиВыбора = ОтображениеКнопкиВыбора.Авто;
		КонецЕсли;
		
		НовыйЭлемент = Элементы.Добавить("Строение" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
		ЗаполнитьЗначенияСвойств(НовыйЭлемент, Элементы.Строение,, "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
		НовыйЭлемент.СписокВыбора.ЗагрузитьЗначения(Элементы.Строение.СписокВыбора.ВыгрузитьЗначения());
		НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_СтроениеПриИзменении");
		
	КонецЕсли;
	
	НовыйЭлемент.КнопкаВыбора = Ложь;
	Добавлять = Новый Массив;
	
	Добавлять.Добавить(Новый РеквизитФормы(НовыйТип.Имя,     Новый ОписаниеТипов("Строка")));
	Добавлять.Добавить(Новый РеквизитФормы(НовыйЭлемент.Имя, Новый ОписаниеТипов("Строка")));
	
	ИзменитьРеквизиты(Добавлять);
	
	НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("Значение", Значение));
	Если НайденныеСтроки.Количество() > 0 Тогда
		НайденныеСтроки[0].ИмяЭлемента = Идентификатор;
	КонецЕсли;
	
	Если СтрСравнить(Значение, НаименованиеПриДобавлениеПроизвольногоПомещения()) <> 0 Тогда
		
		ЭтотОбъект[НовыйТип.Имя]     = Значение;
		Результат                    = НовыйЭлемент.Имя;
		
	Иначе
		
		НайденныеСтроки[0].ПредыдущиеЗначение = "";
		Результат                             = НовыйТип.Имя;
		
	КонецЕсли;
	
	ЭтотОбъект[НовыйЭлемент.Имя] = "";
	
	НовыйТип.ПутьКДанным     = НовыйТип.Имя;
	НовыйЭлемент.ПутьКДанным = НовыйЭлемент.Имя;
	
	Возврат Результат;
	
КонецФункции

&НаКлиенте
Процедура ОбновитьДополнительныеЗдания()
	ОтобразитьДополнительныеЗдания();
	ОбновитьМенюДобавленияСтроенийИПомещений();
КонецПроцедуры

&НаСервере
Функция ОтобразитьДополнительныеЗдания(НаселенныйПунктДетальноПереопределение = Неопределено)
	
	Если НаселенныйПунктДетальноПереопределение <> Неопределено Тогда
		НаселенныйПунктДетально = НаселенныйПунктДетальноПереопределение;
	КонецЕсли;

	Если НаселенныйПунктДетально = Неопределено Тогда
		Возврат Неопределено;
	КонецЕсли;
	
	Удалять = Новый Массив;
	
	КоличествоЭлементов = Элементы.ГруппаСтроенияДополнительно.ПодчиненныеЭлементы.Количество();
	Пока КоличествоЭлементов > 0 Цикл
		
		КоличествоЭлементов = КоличествоЭлементов - 1;

		ЭлементыФормы = Элементы.ГруппаСтроенияДополнительно.ПодчиненныеЭлементы.Получить(КоличествоЭлементов);
		Идентификатор = Сред(ЭлементыФормы.Имя, СтрДлина("ГруппаСтроение") + 1);
		Удалять.Добавить("ТипСтроения" + Идентификатор);
		Удалять.Добавить("Строение" + Идентификатор);
		Элементы.Удалить(Элементы["ГруппаСтроение" + Идентификатор]);
		
		НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("ИмяЭлемента", Идентификатор));
		Если НайденныеСтроки.Количество() > 0 Тогда
			НайденныеСтроки[0].ИмяЭлемента = "";
		КонецЕсли;
		
	КонецЦикла;
	
	КоличествоЭлементов = Элементы.ГруппаПомещенияДополнительно.ПодчиненныеЭлементы.Количество();
	Пока КоличествоЭлементов > 0 Цикл
		
		КоличествоЭлементов = КоличествоЭлементов - 1;
		ЭлементыФормы = Элементы.ГруппаПомещенияДополнительно.ПодчиненныеЭлементы.Получить(КоличествоЭлементов);
		
		Идентификатор = Сред(ЭлементыФормы.Имя, СтрДлина("ГруппаПомещение") + 1);
		Удалять.Добавить("ТипПомещения" + Идентификатор);
		Удалять.Добавить("Помещение" + Идентификатор);
		Элементы.Удалить(Элементы["ГруппаПомещение" + Идентификатор]);
		
		НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("ИмяЭлемента", Идентификатор));
		Если НайденныеСтроки.Количество() > 0 Тогда
			НайденныеСтроки[0].ИмяЭлемента = "";
		КонецЕсли;
		
	КонецЦикла;
	
	ИзменитьРеквизиты(, Удалять);
	
	Если ТипЗнч(НаселенныйПунктДетально.buildings) = Тип("Массив") Тогда
		КоличествоЗданий = НаселенныйПунктДетально.buildings.Количество() - 1;
		
		Результат = Неопределено;
		Для НомерСтроки = 1 По КоличествоЗданий Цикл
			
			Строка        = НаселенныйПунктДетально.buildings[НомерСтроки];
			Идентификатор = СтрЗаменить(Новый УникальныйИдентификатор(),"-", "");
			
			НоваяГруппа = Элементы.Добавить("ГруппаСтроение" + Идентификатор, Тип("ГруппаФормы"), Элементы.ГруппаСтроенияДополнительно);
			ЗаполнитьЗначенияСвойств(НоваяГруппа, Элементы.ГруппаСтроенияОсновная,, "ПутьКДаннымЗаголовка");
			
			НовыйТип = Элементы.Добавить("ТипСтроения" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
			ЗаполнитьЗначенияСвойств(НовыйТип, Элементы.ТипСтроения, , "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
			НовыйТип.СписокВыбора.ЗагрузитьЗначения(Элементы.ТипСтроения.СписокВыбора.ВыгрузитьЗначения());
			НовыйТип.УстановитьДействие("ПриИзменении", "Подключаемый_ТипСтроенияПриИзменении");
			Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
				НовыйТип.КнопкаВыбора = Истина;
				НовыйТип.ОтображениеКнопкиВыбора = ОтображениеКнопкиВыбора.Авто;
			КонецЕсли;
			
			НовыйЭлемент = Элементы.Добавить("Строение" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
			ЗаполнитьЗначенияСвойств(НовыйЭлемент, Элементы.Строение,, "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
			НовыйЭлемент.СписокВыбора.ЗагрузитьЗначения(Элементы.Строение.СписокВыбора.ВыгрузитьЗначения());
			НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_СтроениеПриИзменении");
			НовыйЭлемент.КнопкаВыбора = Ложь;
			
			Если НомерСтроки = КоличествоЗданий Тогда
				Результат = НовыйЭлемент.Имя;
			КонецЕсли;
			
			Добавлять = Новый Массив;
			Добавлять.Добавить(Новый РеквизитФормы(НовыйТип.Имя,     Новый ОписаниеТипов("Строка")));
			Добавлять.Добавить(Новый РеквизитФормы(НовыйЭлемент.Имя, Новый ОписаниеТипов("Строка")));
			
			ИзменитьРеквизиты(Добавлять);
			ЭтотОбъект[НовыйТип.Имя]     = Строка.Type;
			ЭтотОбъект[НовыйЭлемент.Имя] = Строка.Number;
			
			НовыйТип.ПутьКДанным     = НовыйТип.Имя;
			НовыйЭлемент.ПутьКДанным = НовыйЭлемент.Имя;
			
			НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("Значение", Строка.Type));
			Если НайденныеСтроки.Количество() > 0 Тогда
				НайденныеСтроки[0].ИмяЭлемента = Идентификатор;
			КонецЕсли;
			
		КонецЦикла;
	КонецЕсли;
	
	Если ТипЗнч(НаселенныйПунктДетально.Apartments) = Тип("Массив") Тогда
		КоличествоПомещений = НаселенныйПунктДетально.Apartments.Количество() - 1;
		
		Результат = Неопределено;
		Для НомерСтроки = 1 По КоличествоПомещений Цикл
			
			Строка        = НаселенныйПунктДетально.Apartments[НомерСтроки];
			Идентификатор = СтрЗаменить(Новый УникальныйИдентификатор(),"-", "");
			
			НоваяГруппа = Элементы.Добавить("ГруппаПомещение" + Идентификатор, Тип("ГруппаФормы"), Элементы.ГруппаПомещенияДополнительно);
			ЗаполнитьЗначенияСвойств(НоваяГруппа, Элементы.ГруппаПомещенияОсновная,, "ПутьКДаннымЗаголовка");
			
			НовыйТип = Элементы.Добавить("ТипПомещения" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
			ЗаполнитьЗначенияСвойств(НовыйТип, Элементы.ТипПомещения, , "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
			НовыйТип.СписокВыбора.ЗагрузитьЗначения(Элементы.ТипПомещения.СписокВыбора.ВыгрузитьЗначения());
			НовыйТип.УстановитьДействие("ПриИзменении", "Подключаемый_ТипПомещенияПриИзменении");
			Если ОбщегоНазначения.ЭтоМобильныйКлиент() Тогда
				НовыйТип.КнопкаВыбора = Истина;
				НовыйТип.ОтображениеКнопкиВыбора = ОтображениеКнопкиВыбора.Авто;
			КонецЕсли;
			
			НовыйЭлемент = Элементы.Добавить("Помещение" + Идентификатор, Тип("ПолеФормы"), НоваяГруппа);
			ЗаполнитьЗначенияСвойств(НовыйЭлемент, Элементы.Помещение,, "ПутьКДанным, СписокВыбора, ВыделенныйТекст, СвязьПоТипу");
			НовыйЭлемент.СписокВыбора.ЗагрузитьЗначения(Элементы.Помещение.СписокВыбора.ВыгрузитьЗначения());
			НовыйЭлемент.УстановитьДействие("ПриИзменении", "Подключаемый_ПомещениеПриИзменении");
			НовыйЭлемент.КнопкаВыбора = Ложь;
			
			Если НомерСтроки = КоличествоПомещений Тогда
				Результат = НовыйЭлемент.Имя;
			КонецЕсли;
			
			Добавлять = Новый Массив;
			Добавлять.Добавить(Новый РеквизитФормы(НовыйТип.Имя,     Новый ОписаниеТипов("Строка")));
			Добавлять.Добавить(Новый РеквизитФормы(НовыйЭлемент.Имя, Новый ОписаниеТипов("Строка")));
			
			ИзменитьРеквизиты(Добавлять);
			ЭтотОбъект[НовыйТип.Имя]     = Строка.Type;
			ЭтотОбъект[НовыйЭлемент.Имя] = Строка.Number;
			
			НовыйТип.ПутьКДанным     = НовыйТип.Имя;
			НовыйЭлемент.ПутьКДанным = НовыйЭлемент.Имя;
			
			НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("Значение", Строка.Type));
			Если НайденныеСтроки.Количество() > 0 Тогда
				
				НайденныеСтроки[0].ИмяЭлемента = Идентификатор;
				
			Иначе
				
				НовоеПомещение                       = ДополнительныеСтроенияИПомещения.Добавить();
				НовоеПомещение.Тип                   = "Помещение";
				НовоеПомещение.Значение              = НаименованиеПриДобавлениеПроизвольногоПомещения();
				НовоеПомещение.Видимость             = Ложь;
				НовоеПомещение.Ключ                  = "";
				НовоеПомещение.ПредыдущиеЗначение    = Строка.Type;
				НовоеПомещение.ИмяЭлемента           = Идентификатор;
				
			КонецЕсли;
			
		КонецЦикла;
	КонецЕсли;
	
	Возврат Результат;
	
КонецФункции

&НаСервере
Процедура ОтобразитьИнформациюОДатахДействияАдреса(ДействуетС)
	
	Если ВводНовогоАдреса Тогда
		ТекстИсторическийАдрес = "";
		АдресНаДату = ДействуетС;
		Элементы.ГруппаИсторическийАдрес.Видимость = ЗначениеЗаполнено(ДействуетС);
	Иначе
		
		Отбор = Новый Структура("Вид", ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).Ссылка);
		НайденныеСтроки = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
		Если НайденныеСтроки.Количество() = 0 
			ИЛИ (НайденныеСтроки.Количество() = 1 И ПустаяСтрока(НайденныеСтроки[0].Представление)) Тогда
				АдресНаДату = Дата(1, 1, 1);
				Элементы.ГруппаИсторическийАдрес.Видимость = Ложь;
				Элементы.ИсторияИзменений.Видимость = Ложь;
		Иначе
			Результат = ОпределитьДатуДействия(ДействуетС, НайденныеСтроки);
			АдресНаДату = Результат.ДействуетС;
			АдресДействуетС = Результат.ДействуетС;
			
			Если НЕ ЗначениеЗаполнено(Результат.ДействуетС)
				И ПустаяСтрока(Результат.ТекущаяСтрока.Представление) Тогда
					Элементы.ГруппаИсторическийАдрес.Видимость = Ложь;
			ИначеЕсли ЗначениеЗаполнено(Результат.ДействуетПо) Тогда
				ТекстИсторическийАдрес = " " + СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'действует по %1'"), Формат(Результат.ДействуетПо - 10, "ДЛФ=DD"));
			Иначе
				ТекстИсторическийАдрес = НСтр("ru = 'действует по настоящее время.'");
			КонецЕсли;
			ОтобразитьКоличествоЗаписейВИсторииИзменений();
		КонецЕсли;
	КонецЕсли;
	
	Элементы.ТекстПроДатуДействия.Заголовок = ТекстИсторическийАдрес;
	Элементы.АдресНаДату.ФорматРедактирования = ?(ЗначениеЗаполнено(АдресНаДату), "", "ДФ='""" + НачалоУчета() + """'");
	
КонецПроцедуры

&НаСервере
Процедура ОтобразитьКоличествоЗаписейВИсторииИзменений()
	
	ВидКИ = ВидКонтактнойИнформации; // см. УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации
	Отбор = Новый Структура("Вид", ВидКИ.Ссылка);
	НайденныеСтроки = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.НайтиСтроки(Отбор);
	Если НайденныеСтроки.Количество() > 1 Тогда
		Элементы.ИсторияИзмененийГиперссылка.Заголовок = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru = 'История изменений (%1)'"), НайденныеСтроки.Количество());
		Элементы.ИсторияИзмененийГиперссылка.Видимость = Истина;
	ИначеЕсли НайденныеСтроки.Количество() = 1 И ПустаяСтрока(НайденныеСтроки[0].ЗначенияПолей) Тогда
		Элементы.ИсторияИзмененийГиперссылка.Видимость = Ложь;
	Иначе
		Элементы.ИсторияИзмененийГиперссылка.Заголовок = НСтр("ru = 'История изменений'");
		Элементы.ИсторияИзмененийГиперссылка.Видимость = Истина;
	КонецЕсли;

КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ОпределитьДатуДействия(ДействуетС, История)
	
	Результат = Новый Структура("ДействуетПо, ДействуетС, ТекущаяСтрока");
	Если История.Количество() = 0 Тогда
		Возврат Результат;
	КонецЕсли;
	
	ТекущаяСтрока        = Неопределено;
	ДействуетПо          = Неопределено;
	Минимум              = -1;
	МинимумСравнительный = Неопределено;
	
	Для каждого СтрокаИстория Из История Цикл
		Дельта = СтрокаИстория.ДействуетС - ДействуетС;
		Если Дельта <= 0 И (МинимумСравнительный = Неопределено ИЛИ Дельта > МинимумСравнительный) Тогда
			ТекущаяСтрока        = СтрокаИстория;
			МинимумСравнительный = Дельта;
		КонецЕсли;

		Если Минимум = -1 Тогда
			Минимум       = Дельта + 1;
			ТекущаяСтрока = СтрокаИстория;
		КонецЕсли;
		Если Дельта > 0 И МодульЧисла(Дельта) < МодульЧисла(Минимум) Тогда
			ДействуетПо = СтрокаИстория.ДействуетС;
			Минимум     = МодульЧисла(Дельта);
		КонецЕсли;
	КонецЦикла;
	
	Результат.ДействуетПо   = ДействуетПо;
	Результат.ДействуетС    = ТекущаяСтрока.ДействуетС;
	Результат.ТекущаяСтрока = ТекущаяСтрока;
	
	Возврат Результат;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция МодульЧисла(Число)
	Возврат Макс(Число, -Число);
КонецФункции

// Параметры:
//  Элемент - ПолеФормы
//
&НаКлиенте
Процедура Подключаемый_ТипСтроенияПриИзменении(Элемент)
	
	Идентификатор = Сред(Элемент.Имя, СтрДлина("ТипСтроения") + 1);
	НайденныеСтрокиСтарые = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("ИмяЭлемента", Идентификатор));
	Если НайденныеСтрокиСтарые.Количество() > 0 Тогда
		СтароеЗначение = НайденныеСтрокиСтарые[0].Значение;
	КонецЕсли;
	
	Значение = ЭтотОбъект[Элемент.Имя];
	
	НайденныеСтрокиНовый = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("Значение", Значение));
	Если НайденныеСтрокиНовый.Количество() > 0 Тогда
		
		Если НайденныеСтрокиНовый[0].Видимость = Ложь Тогда
			ЭтотОбъект[Элемент.Имя] = СтароеЗначение; // Такое уже значение есть на форме, откатываем на старое.
			Возврат;
		КонецЕсли;
		НайденныеСтрокиСтарые[0].ИмяЭлемента = "";
		НайденныеСтрокиНовый[0].ИмяЭлемента  = Идентификатор;
	КонецЕсли;
	
	Для каждого Помещения Из НаселенныйПунктДетально.buildings Цикл
		Если СтрСравнить(Помещения.Type, СтароеЗначение) = 0 Тогда
			Помещения.Type = ЭтотОбъект[Элемент.Имя];
			ОбновитьПредставлениеАдреса();
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	ОбновитьМенюДобавленияСтроенийИПомещений();
	
	Модифицированность = Истина;
	
КонецПроцедуры

// Параметры:
//  Элемент - ПолеФормы
//
&НаКлиенте
Процедура Подключаемый_СтроениеПриИзменении(Элемент)
	
	Идентификатор = Сред(Элемент.Имя, СтрДлина("Строение") + 1);
	
	НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("ИмяЭлемента", Идентификатор));
	Если НайденныеСтроки.Количество() > 0 Тогда
		Значение = НайденныеСтроки[0].Значение;
	Иначе
		Возврат;
	КонецЕсли;

	ЭтоНовый = Истина;
	Для ИндексПозиции = 0 По НаселенныйПунктДетально.buildings.Количество() - 1 Цикл
		Помещения = НаселенныйПунктДетально.buildings[ИндексПозиции];
		Если СтрСравнить(Помещения.Type, Значение) = 0 Тогда
			Если ЗначениеЗаполнено(ЭтотОбъект[Элемент.Имя]) Тогда
				Помещения.Number = ЭтотОбъект[Элемент.Имя];
			Иначе
				НаселенныйПунктДетально.buildings.Удалить(ИндексПозиции);
			КонецЕсли;
			ЭтоНовый = Ложь;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если ЭтоНовый Тогда
		НаселенныйПунктДетально.buildings.Добавить(ЗначениеСтроенияИлиПомещения(Значение, ЭтотОбъект[Элемент.Имя]));
	КонецЕсли;
	
	ОбновитьПредставлениеАдреса();
	
	Модифицированность = Истина;
	
КонецПроцедуры

// Параметры:
//  Элемент - ПолеФормы
// 
&НаКлиенте
Процедура Подключаемый_ТипПомещенияПриИзменении(Элемент)
	
	Идентификатор = Сред(Элемент.Имя, СтрДлина("ТипПомещения") + 1);
	НайденныеСтрокиСтарые = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("ИмяЭлемента", Идентификатор));
	Если НайденныеСтрокиСтарые.Количество() > 0 Тогда
		СтароеЗначение = НайденныеСтрокиСтарые[0].ПредыдущиеЗначение;
	КонецЕсли;
	
	Значение = ПерваяБукваЗаглавная(ЭтотОбъект[Элемент.Имя]);
	Если ПустаяСтрока(Значение) Тогда
		ЭтотОбъект[Элемент.Имя] = СтароеЗначение; // Такое значение есть на форме, откатываем на старое.
		Возврат;
	КонецЕсли;
	
	НайденныеСтрокиНовый = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("Значение", Значение)); 
	Если НайденныеСтрокиНовый.Количество() > 0 Тогда
		
		Если НайденныеСтрокиНовый[0].Видимость = Ложь Тогда
			ЭтотОбъект[Элемент.Имя] = СтароеЗначение; // Такое значение есть на форме, откатываем на старое.
			Возврат;
		КонецЕсли;
		
		НайденныеСтрокиНовый[0].ИмяЭлемента         = Идентификатор;
		НайденныеСтрокиСтарые[0].ИмяЭлемента        = "";
		Если СтрСравнить(НайденныеСтрокиСтарые[0].Значение, НаименованиеПриДобавлениеПроизвольногоПомещения()) <> 0 Тогда
			НайденныеСтрокиСтарые[0].ПредыдущиеЗначение = ЭтотОбъект[Элемент.Имя];
		Иначе
			НайденныеСтрокиСтарые[0].ПредыдущиеЗначение =  НаименованиеПриДобавлениеПроизвольногоПомещения();
		КонецЕсли;
	Иначе
		
		НовоеПомещение                       = ДополнительныеСтроенияИПомещения.Добавить();
		НовоеПомещение.Тип                   = "Помещение";
		НовоеПомещение.Значение              = Значение;
		НовоеПомещение.Видимость             = Ложь;
		НовоеПомещение.Ключ                  = "";
		НовоеПомещение.ПредыдущиеЗначение    = ЭтотОбъект[Элемент.Имя];
		НовоеПомещение.ИмяЭлемента           = Идентификатор;
		НайденныеСтрокиСтарые[0].ИмяЭлемента = "";
		
	КонецЕсли;
	
	Для каждого Помещения Из НаселенныйПунктДетально.Apartments Цикл
		Если СтрСравнить(Помещения.Type, СтароеЗначение) = 0 Тогда
			Помещения.Type = ЭтотОбъект[Элемент.Имя];
			ОбновитьПредставлениеАдреса();
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	ОбновитьМенюДобавленияСтроенийИПомещений();
	
	Модифицированность = Истина;
	
КонецПроцедуры

// Параметры:
//  Элемент - ПолеФормы
// 
&НаКлиенте
Процедура Подключаемый_ПомещениеПриИзменении(Элемент)
	
	Идентификатор = Сред(Элемент.Имя, СтрДлина("Помещение") + 1);
	
	НайденныеСтроки = ДополнительныеСтроенияИПомещения.НайтиСтроки(Новый Структура("ИмяЭлемента", Идентификатор));
	Если НайденныеСтроки.Количество() > 0 Тогда
		Если СтрСравнить(НайденныеСтроки[0].Значение, НаименованиеПриДобавлениеПроизвольногоПомещения()) <> 0 Тогда
			Значение = НайденныеСтроки[0].Значение;
		Иначе
			Значение = НайденныеСтроки[0].ПредыдущиеЗначение;
		КонецЕсли;
	Иначе
		Возврат;
	КонецЕсли;
	
	ЭтоНовый = Истина;
	Для ИндексПозиции = 0 По НаселенныйПунктДетально.Apartments.Количество() - 1 Цикл
		Помещения = НаселенныйПунктДетально.Apartments[ИндексПозиции];
		Если СтрСравнить(Помещения.Type, Значение) = 0 Тогда
			Если ЗначениеЗаполнено(ЭтотОбъект[Элемент.Имя]) Тогда
				Помещения.Number = ЭтотОбъект[Элемент.Имя];
			Иначе
				НаселенныйПунктДетально.Apartments.Удалить(ИндексПозиции);
			КонецЕсли;
			ЭтоНовый = Ложь;
			Прервать;
		КонецЕсли;
	КонецЦикла;
	
	Если ЭтоНовый Тогда
		НаселенныйПунктДетально.Apartments.Добавить(ЗначениеСтроенияИлиПомещения(Значение, ЭтотОбъект[Элемент.Имя]));
	КонецЕсли;
	ОбновитьПредставлениеАдреса();
	
	Модифицированность = Истина;
	
КонецПроцедуры

&НаКлиенте
Процедура УдалитьПомещениеИзАдреса(УдаляемыйТипПомещения)
	
	Для ИндексПозиции = 0 По НаселенныйПунктДетально.Apartments.Количество() - 1 Цикл
		СведенияОПомещении = НаселенныйПунктДетально.Apartments[ИндексПозиции];
		Если СтрСравнить(СведенияОПомещении.Type, УдаляемыйТипПомещения) =0 Тогда
			НаселенныйПунктДетально.Apartments.Удалить(ИндексПозиции);
			Возврат;
		КонецЕсли;
	КонецЦикла;

КонецПроцедуры

&НаКлиенте
Процедура ОбновитьМенюДобавленияСтроенийИПомещений()
	
	Для каждого СтроениеПомещение Из ДополнительныеСтроенияИПомещения Цикл
		
		Если ЗначениеЗаполнено(СтроениеПомещение.Ключ) Тогда
			
			Если ЗначениеЗаполнено(СтроениеПомещение.ИмяЭлемента)
				Или СтрСравнить(СтроениеПомещение.Значение, ТипПомещения) = 0
				Или СтрСравнить(СтроениеПомещение.Значение, ТипСтроения)  = 0 Тогда
					СтроениеПомещение.Видимость = Ложь;
					Элементы["Добавить_"+ СтроениеПомещение.Ключ].Видимость = Ложь;
			Иначе
					СтроениеПомещение.Видимость = Истина;
					Элементы["Добавить_"+ СтроениеПомещение.Ключ].Видимость = Истина;
			КонецЕсли;
		
		КонецЕсли;
	
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте 
Процедура СообщитьОбОшибкахЗаполнения(СписокОшибок, ПредупреждатьОбОтсутствии, ТребуетсяОбновление = Ложь)
	
	ОчиститьСообщения();
	
	КоличествоОшибок = СписокОшибок.Количество();
	Если КоличествоОшибок = 0 И ПредупреждатьОбОтсутствии Тогда
		Элементы.ГруппаОписаниеНедоступностиСервера.Видимость = Ложь;
		// Нет ошибок
		Если НЕ ВебСервисИспользуется И ТребуетсяОбновление Тогда
			Если ЕстьПравоЗагружатьКлассификатор Тогда
				СообщениеОПроверкеАдреса = НСтр("ru = 'Адрес введен корректно, но адресные сведения, загруженные в программу, давно не обновлялись.
				|Рекомендуется выполнить обновление и повторить проверку адреса заново.'");
				ВопросОбОбновлениеАдресногоКлассификатора(СообщениеОПроверкеАдреса);
			Иначе
				СообщениеОПроверкеАдреса = НСтр("ru = 'Адрес введен корректно, но адресные сведения, загруженные в программу,
				|давно не обновлялись. Рекомендуется выполнить обновление и повторить проверку адреса заново.
				|Для обновления адресного классификатора обратитесь к администратору.'");
				ПоказатьПредупреждение(, СообщениеОПроверкеАдреса);
			КонецЕсли;
		Иначе
			ПоказатьПредупреждение(, НСтр("ru = 'Адрес введен корректно'"));
		КонецЕсли;
		
		Элементы.ГруппаОписаниеНедоступностиСервера.ТекущаяСтраница = Элементы.СервисДоступен;
		Элементы.СообщениеОбОшибке.Видимость = Ложь;
		Возврат;
	КонецЕсли;
	
	Если КоличествоОшибок = 1 Тогда
		МестоОшибки = СписокОшибок[0].ИмяПоля;
		Если СписокОшибок[0].АдресПроверен = Ложь И НЕ ВебСервисИспользуется Тогда
			ТекстВопроса = НСтр("ru = 'Адрес не может быть проверен.'") + Символы.ПС 
				+ СписокОшибок[0].ТекстОшибки + Символы.ПС + НСтр("ru = 'Загрузить классификатор для проверки адреса?'");
			ПредложениеЗагрузкиКлассификатора(ТекстВопроса);
			Возврат;
		ИначеЕсли ПустаяСтрока(МестоОшибки) Или МестоОшибки = "/" Тогда
			Элементы.ГруппаОписаниеНедоступностиСервера.ТекущаяСтраница = Элементы.СообщениеОбОшибке;
		КонецЕсли;
	КонецЕсли;
	
	Элементы.ГруппаОписаниеНедоступностиСервера.ТекущаяСтраница = Элементы.СообщениеОбОшибке;
	Элементы.ГруппаОписаниеНедоступностиСервера.Видимость = Истина;
	Элементы.СообщениеОбОшибке.Видимость = Истина;
	
	Для Каждого Элемент Из СписокОшибок Цикл
		Если Элемент.ВариантАдреса.Количество() > 0 Тогда
			ДополнительныеПараметры = Новый Структура("НовыйАдрес", Элемент.ВариантАдреса[0]);
			Оповещение = Новый ОписаниеОповещения("ПослеВопросаПроЗаменуИсторическогоАдреса", ЭтотОбъект, ДополнительныеПараметры);
			ТекстВопроса = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(НСтр("ru='%1
				|Обновить адрес?'"), Элемент.ТекстОшибки);
			ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет);
			Возврат;
		КонецЕсли;
	КонецЦикла;
	
	// Сообщаем список с привязкой к полям.
	Для Каждого Элемент Из СписокОшибок Цикл
		ОбщегоНазначенияКлиент.СообщитьПользователю(
			Элемент.ТекстОшибки,,, Элемент.ИмяПоля);
	КонецЦикла;
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеВопросаПроЗаменуИсторическогоАдреса(Результат, ДополнительныеПараметры) Экспорт
	Если Результат = КодВозвратаДиалога.Да Тогда
		ЗаполнитьЗначенияСвойств(НаселенныйПунктДетально, ДополнительныеПараметры.НовыйАдрес);
		УстановитьЗначениеРеквизитовПоКонтактнойИнформации(НаселенныйПунктДетально);
		ОбновитьПредставлениеАдреса();
		Модифицированность = Истина;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ПослеВопросОбОбновление(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = "ОбновитьКлассификатор" Тогда
		Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
			ОповещениеОЗакрытие = Новый ОписаниеОповещения("ПослеЗагрузкиАдресногоКлассификатора", ЭтотОбъект);
			МодульАдресныйКлассификаторКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("АдресныйКлассификаторКлиент");
			МодульАдресныйКлассификаторКлиент.ПоказатьФормуЗагрузкиАдресногоКлассификатора(ОповещениеОЗакрытие);
		КонецЕсли;
	КонецЕсли;
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьАдресКлиент()
	
	РаботаСАдресамиКлиент.ОчиститьАдрес(НаселенныйПунктДетально);
	ОтобразитьДополнительныеЗдания();
	
КонецПроцедуры

&НаСервереБезКонтекста
Процедура НаселенныйПунктУстановитьПоляАдреса(НаселенныйПунктДетально, Знач СведенияОбАдресе, Знач ВключатьУлица)
	
	Если СведенияОбАдресе.Свойство("Адрес") И ТипЗнч(СведенияОбАдресе.Адрес) = Тип("Строка") Тогда
		ПолученныйАдрес = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(СведенияОбАдресе.Адрес, Перечисления.ТипыКонтактнойИнформации.Адрес);
	Иначе
		ПолученныйАдрес = ОпределитьАдресПоИдентификатору(СведенияОбАдресе);
	КонецЕсли;
	
	Если Не ВключатьУлица Тогда
		ВключатьУлица = ЗначениеЗаполнено(ПолученныйАдрес.street);
	КонецЕсли;
	
	ИменаУровнейНаселенногоПункта = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса("Все", ВключатьУлица);
	Для каждого ИмяУровня Из ИменаУровнейНаселенногоПункта Цикл
		Если ПолученныйАдрес.Свойство(ИмяУровня) Тогда
			НаселенныйПунктДетально[ИмяУровня]          = ПолученныйАдрес[ИмяУровня];
			НаселенныйПунктДетально[ИмяУровня + "Type"] = ПолученныйАдрес[ИмяУровня + "Type"];
			НаселенныйПунктДетально[ИмяУровня + "Id"]   = ПолученныйАдрес[ИмяУровня + "Id"];
		КонецЕсли;
	КонецЦикла;
	
	НаселенныйПунктДетально.houseId     = "";
	ЗаполнитьЗначенияСвойств(НаселенныйПунктДетально, ПолученныйАдрес, 
		"areaValue,addressType,admLevels,munLevels,version");
	
	Если ПустаяСтрока(ПолученныйАдрес.street) Тогда
		НаселенныйПунктДетально.streetId = "";
	КонецЕсли;
		
	Если ЗначениеЗаполнено(ПолученныйАдрес.ZipCode) Тогда
		НаселенныйПунктДетально.ZipCode = ПолученныйАдрес.ZipCode;
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ПолученныйАдрес.OKTMO) Тогда
		НаселенныйПунктДетально.OKTMO = ПолученныйАдрес.OKTMO;
	КонецЕсли;
	
	Если (ЗначениеЗаполнено(НаселенныйПунктДетально.Street) 
		И Не ЗначениеЗаполнено(НаселенныйПунктДетально.streetId))
		Или ЗначениеЗаполнено(НаселенныйПунктДетально.HouseNumber)
		Или НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
			УстановитьИдентификаторыАдреса(НаселенныйПунктДетально);
	КонецЕсли;
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция КодСтраны(Страна)
	СведенияОбАдресе = УправлениеКонтактнойИнформацией.ДанныеСтраныМира(Неопределено, Строка(Страна));
	Если СведенияОбАдресе <> Неопределено Тогда
		Возврат СведенияОбАдресе.Код;
	КонецЕсли;
	
	Возврат 0;
КонецФункции

&НаСервере
Процедура УстановитьКлючИспользованияФормы()
	КлючСохраненияПоложенияОкна = Строка(Страна);
	
КонецПроцедуры

////////////////////////////////////////////////////////////////////////////////////////////////////

&НаКлиенте
Процедура ПроверитьДоступностьКлассификатора()
	
	Если Не ЕстьЗагруженныйКлассификатор Тогда
		Возврат;
	КонецЕсли;
	
	Задание = ПроверитьДоступностьКлассификатораВФоне(УникальныйИдентификатор);
	
	НастройкиОжидания = ДлительныеОперацииКлиент.ПараметрыОжидания(ЭтотОбъект);
	НастройкиОжидания.ВыводитьОкноОжидания = Ложь;
	
	Обработчик = Новый ОписаниеОповещения("ПослеПроверкиДоступностиКлассификатораВФоне", ЭтотОбъект);
	ДлительныеОперацииКлиент.ОжидатьЗавершение(Задание, Обработчик, НастройкиОжидания);
КонецПроцедуры

&НаКлиенте
Процедура ПослеПроверкиДоступностиКлассификатораВФоне(Задание, ДополнительныеПараметры) Экспорт
	
	Если Задание = Неопределено Тогда
		Возврат;
	КонецЕсли;
	
	Если Задание.Статус = "Выполнено" Тогда
		ДоступностьКлассификатора = ПолучитьИзВременногоХранилища(Задание.АдресРезультата);
		Если ДоступностьКлассификатора <> Неопределено Тогда
			Элементы.ГруппаОписаниеНедоступностиСервера.ТекущаяСтраница = ?(ДоступностьКлассификатора.Отказ,
			Элементы.СервисНедоступен, Элементы.СервисДоступен);
			Если ДоступностьКлассификатора.Отказ Тогда
				ТекстСообщенияСервиса = НСтр("ru = 'Автоподбор и проверка адреса недоступны:'") + Символы.ПС 
					+ ДоступностьКлассификатора.КраткоеПредставлениеОшибки;
			КонецЕсли;
		КонецЕсли;
	ИначеЕсли Задание.Статус = "Ошибка" Тогда
		Элементы.ГруппаОписаниеНедоступностиСервера.ТекущаяСтраница = Элементы.СервисНедоступен;
		ТекстСообщенияСервиса = НСтр("ru = 'Автоподбор и проверка адреса недоступны:'") + Символы.ПС 
			+ Задание.КраткоеПредставлениеОшибки;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура АвторизацияНаСайтеПоддержкиПользователейЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат <> Неопределено Тогда
		ОбновитьПовторноИспользуемыеЗначения();
		ПроверитьДоступностьКлассификатора();
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  ВыбранноеЗначение - см. АдресныйКлассификаторСлужебный.ОписаниеДомаИЗемельногоУчастка
//
&НаКлиенте
Процедура ЗаполнитьПоляДомовСтроенийЗемельныхУчастков(Знач ВыбранноеЗначение)
	
	Модифицированность = Истина;
	
	НаселенныйПунктДетально.ZIPcode        = ВыбранноеЗначение.Индекс;
	НаселенныйПунктДетально.OKTMO          = ВыбранноеЗначение.ОКТМО;
	НаселенныйПунктДетально.okato          = ВыбранноеЗначение.ОКАТО;
	НаселенныйПунктДетально.ifnsFLCode     = ВыбранноеЗначение.КодИФНСФЛ;
	НаселенныйПунктДетально.ifnsULCode     = ВыбранноеЗначение.КодИФНСЮЛ;
	НаселенныйПунктДетально.ifnsFLAreaCode = ВыбранноеЗначение.КодУчасткаИФНСФЛ;
	НаселенныйПунктДетально.ifnsULAreaCode = ВыбранноеЗначение.КодУчасткаИФНСЮЛ;
	НаселенныйПунктДетально.codeKLADR      = ВыбранноеЗначение.КодКЛАДР;
	
	УстановитьМуниципальныеЧастиАдреса(НаселенныйПунктДетально, ВыбранноеЗначение);
	
	ОбработкаИзмененияАдреса();
	
	Если СтрСравнить(ТипДома, РаботаСАдресамиКлиентСервер.НаименованиеЗемельногоУчастка()) <> 0 Тогда
		ЗаполнитьПоляДомовИСтроений(ВыбранноеЗначение);
	Иначе
		ЗаполнитьПоляЗемельногоУчастка(ВыбранноеЗначение);
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  ВыбранноеЗначение - см. АдресныйКлассификаторСлужебный.ОписаниеДомаИЗемельногоУчастка
//
&НаКлиенте
Процедура ЗаполнитьПоляДомовИСтроений(Знач ВыбранноеЗначение)
	
	НеобходимоПерерисоватьПоляДомов = НаселенныйПунктДетально.buildings.Количество() > 1;
	
	Если ЗначениеЗаполнено(ВыбранноеЗначение.НомерДома) Тогда
		НаселенныйПунктДетально.HouseNumber = ВыбранноеЗначение.НомерДома;
		Если ЗначениеЗаполнено(ВыбранноеЗначение.НаименованиеДома) Тогда
			НаселенныйПунктДетально.HouseType = ПерваяБукваЗаглавная(ВыбранноеЗначение.НаименованиеДома);
		КонецЕсли;
	КонецЕсли;
	
	НаселенныйПунктДетально.buildings.Очистить();
	
	Если ЗначениеЗаполнено(ВыбранноеЗначение.ДополнительныйНомерДома1) Тогда
		СведенияОКорпусе = УправлениеКонтактнойИнформациейКлиентСервер.ЗначениеСтроенияИлиПомещения(
			ПерваяБукваЗаглавная(ВыбранноеЗначение.НаименованиеДополнительногоДома1), ВыбранноеЗначение.ДополнительныйНомерДома1);
		НаселенныйПунктДетально.buildings.Добавить(СведенияОКорпусе);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(ВыбранноеЗначение.ДополнительныйНомерДома2) Тогда
		СведенияОКорпусе = УправлениеКонтактнойИнформациейКлиентСервер.ЗначениеСтроенияИлиПомещения(
			ПерваяБукваЗаглавная(ВыбранноеЗначение.НаименованиеДополнительногоДома2), ВыбранноеЗначение.ДополнительныйНомерДома2);
		НаселенныйПунктДетально.buildings.Добавить(СведенияОКорпусе);
	КонецЕсли;
	
	НаселенныйПунктДетально.houseId = ВыбранноеЗначение.ИдентификаторДома;
	
	ЗаполнитьУровниДомовИЗемельныхУчастков();
	
	// отрисовка
	
	Индекс = НаселенныйПунктДетально.ZipCode;
	ОКТМО  = НаселенныйПунктДетально.OKTMO;
	
	Дом = НаселенныйПунктДетально.HouseNumber;
	Если ЗначениеЗаполнено(НаселенныйПунктДетально.HouseType) Тогда
		ТипДома = НаселенныйПунктДетально.HouseType;
	КонецЕсли;
	
	Если НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
		Строение       = НаселенныйПунктДетально.buildings[0].Number;
		ТипСтроения    = НаселенныйПунктДетально.buildings[0].Type;
		Если НаселенныйПунктДетально.buildings.Количество() > 1 Тогда
			НеобходимоПерерисоватьПоляДомов = Истина;
		КонецЕсли;
	Иначе
		Строение       = "";
	КонецЕсли;
	
	Если НеобходимоПерерисоватьПоляДомов Тогда
		ПодключитьОбработчикОжидания("ОтобразитьДополнительныеЗданияКлиент", 0.1, Истина);
	Иначе
		ОбновитьПредставлениеАдреса();
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  ВыбранноеЗначение - см. АдресныйКлассификаторСлужебный.ОписаниеДомаИЗемельногоУчастка
//
&НаКлиенте
Процедура ЗаполнитьПоляЗемельногоУчастка(Знач ВыбранноеЗначение)
	
	НаселенныйПунктДетально.stead   = ВыбранноеЗначение.НомерДома;
	НаселенныйПунктДетально.steadId = ВыбранноеЗначение.ИдентификаторДома;
	
	Индекс = НаселенныйПунктДетально.ZipCode;
	ОКТМО  = НаселенныйПунктДетально.OKTMO;
	Дом    = НаселенныйПунктДетально.stead;
	
	НаселенныйПунктДетально.buildings.Очистить();
	Строение       = "";
	
	ПодключитьОбработчикОжидания("ОтобразитьДополнительныеЗданияКлиент", 0.1, Истина);
	
КонецПроцедуры

&НаКлиенте
Функция ПерваяБукваЗаглавная(Строка)
	Возврат ВРег(Лев(Строка, 1)) + Сред(НРег(Строка), 2); // Использовать ТРег нельзя.
КонецФункции

&НаКлиенте
Процедура ОтобразитьДополнительныеЗданияКлиент()
	ИмяТекущего = ОтобразитьДополнительныеЗдания();
	
	ОбновитьМенюДобавленияСтроенийИПомещений();
	
	Если ИмяТекущего <> Неопределено Тогда
		ТекущийЭлемент = Элементы[ИмяТекущего];
	КонецЕсли;
	
	ОбновитьПредставлениеАдреса();
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьПредопределенныеВариантыАдреса(Параметры)
	
	Если Параметры.Свойство("Индекс") И ЗначениеЗаполнено(Параметры.Индекс) Тогда
		Индекс = Параметры.Индекс;
		НаселенныйПунктДетально.ZipCode = Индекс;
	КонецЕсли;
	
	Если Параметры.Свойство("Страна") И ПустаяСтрока(НаселенныйПунктДетально.Country) Тогда
		
		Если ТипЗнч(Параметры.Страна) = Тип("СправочникСсылка.СтраныМира") Тогда
			Если ЗначениеЗаполнено(Параметры.Страна) Тогда
				Страна = Параметры.Страна; // СправочникСсылка.СтраныМира
				НаселенныйПунктДетально.Country = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Страна, "Наименование");
			Иначе
				Страна = РаботаСАдресамиКлиентСервер.ОсновнаяСтрана();
				НаселенныйПунктДетально.Country = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Страна, "Наименование");
			КонецЕсли;
		Иначе
			Страна = УправлениеКонтактнойИнформацией.СтранаМираПоКодуИлиНаименованию(Параметры.Страна);
			Если Страна <> Справочники.СтраныМира.ПустаяСсылка() Тогда
				НаселенныйПунктДетально.Country = Параметры.Страна;
			Иначе
				Страна = РаботаСАдресамиКлиентСервер.ОсновнаяСтрана();
				НаселенныйПунктДетально.Country = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(Страна, "Наименование");
			КонецЕсли;
		КонецЕсли;
		
		ПереопределитьТипаАдресаПоСтране(Страна, НаселенныйПунктДетально, СведенияОСтране(Страна), МеждународныйФорматАдреса);
		
	КонецЕсли;
	
	// Возможные варианты дома, строения, квартиры.
	ВариантыДанныхДом = РаботаСАдресамиПовтИсп.ВариантыДанныхДом();
	УстановитьСписокВыбораЭлемента(Элементы.ТипДома, Элементы.Дом, ВариантыДанныхДом);
	
	ВариантыДанныхСтроение = РаботаСАдресамиПовтИсп.ВариантыДанныхСтроение();
	УстановитьСписокВыбораЭлемента(Элементы.ТипСтроения, Элементы.Строение, ВариантыДанныхСтроение);
	
	ВариантыДанныхПомещение = РаботаСАдресамиПовтИсп.ВариантыДанныхПомещение();
	УстановитьСписокВыбораЭлемента(Элементы.ТипПомещения, Элементы.Помещение, ВариантыДанныхПомещение);
	Элементы.ТипПомещения.СписокВыбора.НайтиПоЗначению("").Значение = НаименованиеПриДобавлениеПроизвольногоПомещения();
	
	// Возможно пустые значения, чтобы не смущали.
	Если ПустаяСтрока(Дом) И ПустаяСтрока(ТипДома) Тогда
		ТипДома = ПервыйИлиПустой(Элементы.ТипДома);
	КонецЕсли;
	Если ПустаяСтрока(Строение) И ПустаяСтрока(ТипСтроения) Тогда
		ТипСтроения = ПервыйИлиПустой(Элементы.ТипСтроения);
	КонецЕсли;
	
	Если Параметры.Свойство("ТипПомещения")
		И ВариантыДанныхПомещение.ВариантыТипа.Найти(Параметры.ТипПомещения) <> Неопределено Тогда
			ТипПомещения = Параметры.ТипПомещения;
	КонецЕсли;

	Если ПустаяСтрока(Помещение) И ПустаяСтрока(ТипПомещения) Тогда
		ТипПомещения = ПервыйИлиПустой(Элементы.ТипПомещения);
	КонецЕсли;
	
	Для каждого ВариантДанных Из ВариантыДанныхСтроение.ВариантыТипа Цикл
		ДобавитьОписаниеСтроенияИлиПомещения(ВариантДанных, "Строение");
	КонецЦикла;
	
	Для каждого ВариантДанных Из ВариантыДанныхПомещение.ВариантыТипа Цикл
		
		Если ПустаяСтрока(ВариантДанных) Тогда
			ВариантДанных = НаименованиеПриДобавлениеПроизвольногоПомещения();
		КонецЕсли;
		
		ДобавитьОписаниеСтроенияИлиПомещения(ВариантДанных, "Помещение", СтрЗаменить(ВариантДанных, "/", ""));
		
	КонецЦикла;
	
КонецПроцедуры

// Возвращает первый элемент из списка.
//
// Параметры:
//     СписокДанных - СписокЗначений
//                  - Массив
//                  - ПолеФормы.
//
// Возвращаемое значение:
//     Произвольный - первый элемент.
//     Неопределено - нет первого элемента.
// 
&НаСервереБезКонтекста
Функция ПервыйИлиПустой(Знач СписокДанных)
	
	ТипСписка = ТипЗнч(СписокДанных);
	Если ТипСписка = Тип("СписокЗначений") И СписокДанных.Количество() > 0 Тогда
		Возврат СписокДанных[0].Значение;
	ИначеЕсли ТипСписка = Тип("Массив") И СписокДанных.Количество() > 0 Тогда
		Возврат СписокДанных[0];
	ИначеЕсли ТипСписка = Тип("ПолеФормы") Тогда
		Возврат ПервыйИлиПустой(СписокДанных.СписокВыбора);
	КонецЕсли;
	
	Возврат Неопределено;
КонецФункции

&НаСервереБезКонтекста
Функция СведенияОРегионе(НаименованиеСубъектаРФ, ТипОбъекта)
	
	МодульАдресныйКлассификаторСлужебный = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификаторСлужебный");
	СведенияОРегионе = МодульАдресныйКлассификаторСлужебный.СведенияОРегионе(НаименованиеСубъектаРФ, ТипОбъекта);
	
	Возврат СведенияОРегионе;
	
КонецФункции

&НаСервереБезКонтекста
Функция ПроверитьДоступностьКлассификатораВФоне(Знач УникальныйИдентификатор)
	ИмяМетода = "Обработки.РасширенныйВводКонтактнойИнформации.ПроверитьДоступностьКлассификатора";
	
	НастройкиЗапуска = ДлительныеОперации.ПараметрыВыполненияВФоне(УникальныйИдентификатор);
	НастройкиЗапуска.НаименованиеФоновогоЗадания = НСтр("ru = 'Проверка доступности сервиса адресного классификатора'");
	
	Возврат ДлительныеОперации.ВыполнитьВФоне(ИмяМетода, Новый Структура, НастройкиЗапуска);
КонецФункции

&НаСервереБезКонтекста
Функция ОпределитьАдресПоИдентификатору(СведенияОбАдреса)
	Возврат Обработки.РасширенныйВводКонтактнойИнформации.СписокРеквизитовНаселенныйПункт(СведенияОбАдреса);
КонецФункции

&НаСервереБезКонтекста
Функция КонтактнаяИнформацияПоПредставлению(ПредставлениеАдреса, Комментарий = "", РазбиватьНаПоля = Ложь)
	
	Адрес = УправлениеКонтактнойИнформациейСлужебный.КонтактнаяИнформацияПоПредставлению(ПредставлениеАдреса, Перечисления.ТипыКонтактнойИнформации.Адрес, РазбиватьНаПоля);
	Адрес.comment = Комментарий;
	Возврат Адрес;
	
КонецФункции

&НаКлиенте
Процедура ПоказатьАдресВСвободнойФорме()
	
	ОчиститьАдресКлиент();
	УдалитьСтрануИзПредставления();
	
	НаселенныйПунктДетально.value       = ПредставлениеАдреса;
	НаселенныйПунктДетально.addressType = УправлениеКонтактнойИнформациейКлиентСервер.АдресВСвободнойФорме();
	НаселенныйПунктДетально.comment     = Комментарий;
	
	НаселенныйПунктДетально.country     =  НаименованиеСтраны(Страна,
		ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).МеждународныйФорматАдреса);
	
	Если Элементы.СтранаВСвободнойФорме.Доступность Тогда
		Элементы.СтранаВСвободнойФорме.Видимость = Не ВидКонтактнойИнформации.ТолькоНациональныйАдрес;
	КонецЕсли;
	
	Элементы.АдресПредставлениеКомментарий.ТекущаяСтраница = Элементы.ВСвободнойФорме;
	Элементы.АдресВСвободнойФорме.Пометка                  = Истина;
	Элементы.АдминистративноТерриториальноеДеление.Пометка = Ложь;
	Элементы.МуниципальноеДеление.Пометка                  = Ложь;
	НаселенныйПунктДетально.AddressType                    = УправлениеКонтактнойИнформациейКлиентСервер.АдресВСвободнойФорме();
	
	ПоказатьПодсказкуПоТипАдреса();
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция СписокАвтоподбораНаселенногоПункта(Текст, ТипАдреса)
	
	ДополнительныеПараметры = УправлениеКонтактнойИнформациейСлужебный.ПараметрыАвтоподбораАдреса();
	ДополнительныеПараметры.Уровни    = "1,2,3,4,5,6,7";
	ДополнительныеПараметры.ТипАдреса = ТипАдреса;
	
	Результат = Обработки.РасширенныйВводКонтактнойИнформации.СписокАвтоподбораНаселенногоПункта(Текст, ДополнительныеПараметры);
	УправлениеКонтактнойИнформациейСлужебный.ФорматированиеРезультатовАвтоподбора(Результат.Данные, Текст, ПустаяСтрока(ТипАдреса));
	Возврат Результат;
	
КонецФункции

&НаСервереБезКонтекста
Функция СписокАвтоподбораУлицы(Текст, ПараметрыАвтоподбора)
	
	Результат = Обработки.РасширенныйВводКонтактнойИнформации.СписокАвтоподбораУлицы(Текст, ПараметрыАвтоподбора);
	УправлениеКонтактнойИнформациейСлужебный.ФорматированиеРезультатовАвтоподбора(Результат.Данные, Текст, Ложь);
	Возврат Результат;
	
КонецФункции

&НаСервереБезКонтекста
Функция СписокАвтоподбораВариантовДомов(Идентификатор, Текст)
	Возврат Обработки.РасширенныйВводКонтактнойИнформации.СписокАвтоподбораНомераДомов(Идентификатор, Текст);
КонецФункции

&НаСервереБезКонтекста
Функция СписокАвтоподбораЗемельныхУчастков(Идентификатор, Текст)
	Возврат Обработки.РасширенныйВводКонтактнойИнформации.СписокАвтоподбораЗемельныхУчастков(Идентификатор, Текст);
КонецФункции

&НаСервере
Процедура ПриСозданииНаСервереХранитьИсториюИзменений()
	
	Если ВидКонтактнойИнформации.ХранитьИсториюИзменений Тогда
		Если Параметры.Свойство("КонтактнаяИнформацияОписаниеДополнительныхРеквизитов") Тогда
			Для каждого СтрокаКИ Из Параметры.КонтактнаяИнформацияОписаниеДополнительныхРеквизитов Цикл
				НоваяСтрока = КонтактнаяИнформацияОписаниеДополнительныхРеквизитов.Добавить();
				ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаКИ);
			КонецЦикла;
		Иначе
			Элементы.ИсторияИзменений.Видимость           = Ложь;
		КонецЕсли;
		Элементы.ИсторияИзмененийГиперссылка.Видимость = НЕ Параметры.Свойство("ИзФормыИстории");
		ВводНовогоАдреса = ?(Параметры.Свойство("ВводНовогоАдреса"), Параметры.ВводНовогоАдреса, Ложь);
		Если ВводНовогоАдреса Тогда
			ДействуетС = Параметры.ДействуетС;
		Иначе
			ДействуетС = ?(ЗначениеЗаполнено(Параметры.ДействуетС), Параметры.ДействуетС, ТекущаяДатаСеанса());
		КонецЕсли;
		ОтобразитьИнформациюОДатахДействияАдреса(ДействуетС);
	Иначе
		Элементы.ИсторияИзменений.Видимость           = Ложь;
		Элементы.ГруппаИсторическийАдрес.Видимость    = Ложь;
	КонецЕсли;

КонецПроцедуры

&НаСервере
Процедура УстановитьТипАдресаИзПараметра(ТипАдресаИзПараметра)
	
	Если СтрСравнить(ТипАдресаИзПараметра, "АдминистративноТерриториальный") = 0 Или СтрСравнить(ТипАдресаИзПараметра, РаботаСАдресамиКлиентСервер.АдминистративноТерриториальныйАдрес()) = 0 Тогда
		НаселенныйПунктДетально.AddressType = РаботаСАдресамиКлиентСервер.АдминистративноТерриториальныйАдрес();
		ТипАдреса = РаботаСАдресамиКлиентСервер.АдминистративноТерриториальныйАдрес();
	ИначеЕсли СтрСравнить(ТипАдресаИзПараметра, "ВСвободнойФорме") = 0 Тогда
		НаселенныйПунктДетально.AddressType = УправлениеКонтактнойИнформациейКлиентСервер.АдресВСвободнойФорме();
		ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.АдресВСвободнойФорме();
	ИначеЕсли СтрСравнить(ТипАдресаИзПараметра, "ЕАЭС") = 0 Тогда
		НаселенныйПунктДетально.AddressType = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС();
		ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС();
	Иначе
		НаселенныйПунктДетально.AddressType = РаботаСАдресамиКлиентСервер.МуниципальныйАдрес();
		ТипАдреса = РаботаСАдресамиКлиентСервер.МуниципальныйАдрес();
	КонецЕсли;
	
	Элементы.ФормаВсеДействияИзмененияАдреса.Видимость = Ложь;
	Элементы.ДекорацияМуниципальный.ОтображениеПодсказки = ОтображениеПодсказки.Нет;
	Элементы.ДекорацияАдминистративноТерриториальный.ОтображениеПодсказки = ОтображениеПодсказки.Нет;
	
КонецПроцедуры

&НаКлиенте
Функция ЭтоМеждународныйАдрес(ТипАдреса)
	Возврат СтрСравнить(УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес(), ТипАдреса) = 0;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция ЭтоЗемельныйУчасток(ТипДома)
	Возврат СтрСравнить(РаботаСАдресамиКлиентСервер.НаименованиеЗемельногоУчастка(), ТипДома) = 0;
КонецФункции

// Предлагает загрузить адресный классификатор.
//
//  Параметры:
//      Текст  - Строка        - дополнительный текст предложения.
//      Регион - Число
//             - Строка - код или название региона для загрузки.
//
&НаКлиенте
Процедура ПредложениеЗагрузкиКлассификатора(Знач Текст = "", Знач ДанныеОбАдресе = Неопределено)
	
	Если Не ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		Возврат;
	КонецЕсли;
	
	НеЗагружатьАдресныйКлассификатор = ПараметрыПриложения.Получить("АдресныйКлассификатор.НеЗагружатьКлассификатор");
	Если ДанныеОбАдресе <> Неопределено 
		И (НеЗагружатьАдресныйКлассификатор = Неопределено
		ИЛИ НеЗагружатьАдресныйКлассификатор = Ложь) Тогда
		
			Регион = ДанныеОбАдресе.Представление;
			ТипПараметраРегиона = ТипЗнч(Регион);
			ПараметрыФормы = Новый Структура;
			ПараметрыЗагрузки = Новый Структура;
			ПараметрыЗагрузки.Вставить("ДанныеОбАдресе", ДанныеОбАдресе);
			ПараметрыФормы.Вставить("ТекстПредупреждения", Текст);
			
			Если ТипПараметраРегиона = Тип("Число") Тогда
				ПараметрыЗагрузки.Вставить("КодРегионаДляЗагрузки", Регион);
				
			ИначеЕсли ТипПараметраРегиона = Тип("Строка") Тогда
				ПараметрыЗагрузки.Вставить("НазваниеРегиона", Регион);
				ПараметрыФормы.Вставить("НазваниеРегиона", Регион);
			КонецЕсли;
			
			ДополнительныеПараметры = Новый Структура;
			ДополнительныеПараметры.Вставить("ПараметрыЗагрузки", ПараметрыЗагрузки);
			ДополнительныеПараметры.Вставить("ПараметрыФормы", ПараметрыФормы);
			
			Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
				Оповещение = Новый ОписаниеОповещения("ПослеВводаЛогинИПароля", ЭтотОбъект, ДополнительныеПараметры);
				
				МодульАдресныйКлассификаторКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("АдресныйКлассификаторКлиент");
				МодульАдресныйКлассификаторКлиент.АвторизоватьНаСайтеПоддержкиПользователей(Оповещение, ЭтотОбъект);
			КонецЕсли;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеВводаЛогинИПароля(Знач РезультатВопроса, Знач ДополнительныеПараметры) Экспорт
	
	Если РезультатВопроса = Неопределено Тогда
		Оповещение = Новый ОписаниеОповещения("ПредложениеЗагрузкиКлассификатораЗавершение", ЭтотОбъект, ДополнительныеПараметры.ПараметрыЗагрузки);
		ОткрытьФорму("Обработка.РасширенныйВводКонтактнойИнформации.Форма.ЗагрузкаАдресногоКлассификатора", ДополнительныеПараметры.ПараметрыФормы, ЭтотОбъект,,,, Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
		Возврат;
	КонецЕсли;
	
	УстановитьНаселенныйПунктПослеВыбора(ДополнительныеПараметры.ПараметрыЗагрузки.ДанныеОбАдресе);
	ОбновитьПовторноИспользуемыеЗначения();
	ВебКлассификаторДоступен = Истина;
	СообщениеОНеобходимостиЗагрузкиКлассификатора();
	
КонецПроцедуры

&НаКлиенте
Процедура ПредложениеЗагрузкиКлассификатораЗавершение(Знач РезультатВопроса, Знач ДополнительныеПараметры) Экспорт
	
	Если РезультатВопроса <> КодВозвратаДиалога.Да Тогда
		УстановитьНаселенныйПунктПослеВыбора(ДополнительныеПараметры.ДанныеОбАдресе);
		Возврат;
	КонецЕсли;
	
	ЗагрузитьАдресныйКлассификатор(ДополнительныеПараметры);
	
КонецПроцедуры

&НаКлиенте
Процедура СообщениеОНеобходимостиЗагрузкиКлассификатора()
	
	АдресныеСведенияЗагружены = АдресныеСведенияКлассификатораЗагружены(НаименованиеРегиона(НаселенныйПунктДетально));
	Если ВебКлассификаторДоступен Или АдресныеСведенияЗагружены.РегионЗагружен Тогда
		Элементы.ГруппаИнформация.Видимость            = Ложь;
		Элементы.Дом.КнопкаВыбора                      = Истина;
		Элементы.Улица.КнопкаВыбора                    = Истина;
		АвтоподборДоступен                             = Истина;
		Элементы.ПроверитьЗаполнениеАдреса.Доступность = Истина;
	ИначеЕсли АдресныеСведенияЗагружены.АдресныйКлассификаторДоступен Тогда
		Элементы.ГруппаИнформация.Видимость = Истина;
	КонецЕсли;

КонецПроцедуры

&НаКлиенте
Процедура УстановитьНаселенныйПунктПослеВыбора(Знач ДанныеОбАдресе)
	
	НаселенныйПунктУстановитьПоляАдреса(НаселенныйПунктДетально, ДанныеОбАдресе, Ложь);
	ОбработкаИзмененияАдреса();
	УстановитьФлагиВМенюПоТипуАдреса();
	
КонецПроцедуры

// Загружает адресный классификатор.
//
&НаКлиенте
Процедура ЗагрузитьАдресныйКлассификатор(Знач ДополнительныеПараметры = Неопределено)
	
	Если ОбщегоНазначенияКлиент.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		МодульАдресныйКлассификаторКлиент = ОбщегоНазначенияКлиент.ОбщийМодуль("АдресныйКлассификаторКлиент");
		МодульАдресныйКлассификаторКлиент.ЗагрузитьАдресныйКлассификатор(ДополнительныеПараметры);
	КонецЕсли;
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция СведенияОСтране(Страна)
	Возврат УправлениеКонтактнойИнформацией.ДанныеСтраныМира(, Страна);
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция НаименованиеПриДобавлениеПроизвольногоПомещения()
	Возврат НСтр("ru = 'Другое'");
КонецФункции

&НаСервере
Функция ОпределитьЗначениеАдреса(Параметры)
	
	Если Параметры.Свойство("Значение") Тогда
		Если ПустаяСтрока(Параметры.Значение) И ЗначениеЗаполнено(Параметры.ЗначенияПолей) Тогда
			ЗначенияПолей = Параметры.ЗначенияПолей;
		Иначе
			ЗначенияПолей = Параметры.Значение;
		КонецЕсли;
	Иначе
		ЗначенияПолей = Параметры.ЗначенияПолей;
	КонецЕсли;
	
	Если ПустаяСтрока(ЗначенияПолей) И ЗначениеЗаполнено(Параметры.Представление) Тогда
		ЗначенияПолей = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияПоПредставлению(Параметры.Представление,
			Перечисления.ТипыКонтактнойИнформации.Адрес);
			Модифицированность = Истина;
	КонецЕсли;
	
	Возврат ЗначенияПолей;

КонецФункции

&НаСервере
Функция ИзвлечьСтарыйФорматАдреса(Знач ЗначенияПолей, Знач ТипКонтактнойИнформации)
	
	Перем XDTOКонтактная, РезультатыЧтения;
	
	Если УправлениеКонтактнойИнформациейКлиентСервер.ЭтоКонтактнаяИнформацияВXML(ЗначенияПолей)
		И ТипКонтактнойИнформации = Перечисления.ТипыКонтактнойИнформации.Адрес Тогда
		РезультатыЧтения = Новый Структура;
		XDTOКонтактная = УправлениеКонтактнойИнформациейЛокализация.КонтактнаяИнформацияИзXML(ЗначенияПолей, ТипКонтактнойИнформации, РезультатыЧтения);
		Если РезультатыЧтения.Свойство("ТекстОшибки") Тогда
			// Распознали с ошибками, сообщим при открытии.
			ТекстПредупрежденияПриОткрытии = РезультатыЧтения.ТекстОшибки;
			XDTOКонтактная.Представление   = Параметры.Представление;
			XDTOКонтактная.Состав.Страна   = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОсновнаяСтрана, "Наименование");
		КонецЕсли;
	Иначе
		XDTOКонтактная = УправлениеКонтактнойИнформациейЛокализация.АдресXMLВXDTO(ЗначенияПолей, Параметры.Представление, );
		Если Параметры.Свойство("Страна") И ЗначениеЗаполнено(Параметры.Страна) Тогда
			Если ТипЗнч(Параметры.Страна) = ТипЗнч(Справочники.СтраныМира.ПустаяСсылка()) Тогда
				СтранаСсылка = Параметры.Страна; // СправочникСсылка.СтраныМира
				XDTOКонтактная.Состав.Страна = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(СтранаСсылка , "Наименование");
			Иначе
				XDTOКонтактная.Состав.Страна = Строка(Параметры.Страна);
			КонецЕсли;
		Иначе
			XDTOКонтактная.Состав.Страна = ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ОсновнаяСтрана, "Наименование");
		КонецЕсли;
	КонецЕсли;
	Если Параметры.Комментарий <> Неопределено Тогда
		// Ставим новый комментарий, иначе он придет из информации.
		XDTOКонтактная.Комментарий = Параметры.Комментарий;
	КонецЕсли;
	Возврат XDTOКонтактная;

КонецФункции

&НаСервере
Процедура СформироватьМенюДобавленияСтроенийИПомещений()
	
	Для каждого СтроениеИлиПомещение Из ДополнительныеСтроенияИПомещения Цикл
		
		Если ЗначениеЗаполнено(СтроениеИлиПомещение.Ключ) Тогда
			ИмяКоманды                        = "Добавить_" + СтроениеИлиПомещение.Ключ;
			Команда                           = Команды.Добавить(ИмяКоманды);
			Команда.Подсказка                 = НСтр("ru = 'Добавить'") + " " + НРег(СтроениеИлиПомещение.Значение);
			Команда.Действие                  = "Подключаемый_ДобавитьСтроениеИлиПомещение";
			Команда.ИзменяетСохраняемыеДанные = Истина;
			
			Группа = ?(СтроениеИлиПомещение.Тип = "Строение", Элементы.ГруппаДобавлениеСтроения, Элементы.ГруппаДобавлениеПомещения);
			Кнопка            = Элементы.Добавить(ИмяКоманды, Тип("КнопкаФормы"), Группа);
			Кнопка.ИмяКоманды = ИмяКоманды;
			Кнопка.Заголовок  = СтроениеИлиПомещение.Значение;
		КонецЕсли;
		
	КонецЦикла;
	
КонецПроцедуры

&НаСервере
Процедура ДобавитьОписаниеСтроенияИлиПомещения(ИмяПомещенияИлиСтроения, Тип, Ключ = "")
	
	ОписаниеПомещения               = ДополнительныеСтроенияИПомещения.Добавить();
	ОписаниеПомещения.Значение      = ИмяПомещенияИлиСтроения;
	ОписаниеПомещения.Тип           = Тип;
	ОписаниеПомещения.Видимость     = Истина;
	ОписаниеПомещения.Ключ          = "key" + СтрЗаменить(Новый УникальныйИдентификатор, "-", "");
	ОписаниеПомещения.ПредыдущиеЗначение = ИмяПомещенияИлиСтроения;
	
КонецПроцедуры

&НаКлиенте
Функция ЗначениеСтроенияИлиПомещения(Тип, Значение)
	Возврат Новый Структура("type, number", Тип, Значение);
КонецФункции

&НаКлиенте
Процедура ОбновитьПредставлениеАдреса()
	
	РаботаСАдресамиКлиентСервер.ОбновитьПредставлениеАдреса(НаселенныйПунктДетально, ВидКонтактнойИнформации.ВключатьСтрануВПредставление);
	ПредставлениеАдреса = НаселенныйПунктДетально.Value;
	Если ВидКонтактнойИнформации.ВключатьСтрануВПредставление И УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType) Тогда
		УдалитьСтрануИзПредставления();
	КонецЕсли;
	
	ПоказатьПодсказкуПоТипАдреса();
	
КонецПроцедуры

&НаКлиенте
Процедура ИзменитьСведенияОНаселенномПункте()
	
	Если ПустаяСтрока(НаселенныйПункт) Тогда
		ОчиститьНаселенныйПункт();
		Возврат;
	КонецЕсли;
	
	АдресВосстановлен = Ложь;
	ОчиститьИдентификаторыАдреса();
	Если РаботаСАдресамиКлиентСервер.ЭтоОсновнаяСтрана(Страна) И Не МеждународныйФорматАдреса Тогда
		
		ИменаУровнейАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(НаселенныйПунктДетально.AddressType, Ложь);
		АдресВосстановлен = ВосстановитьНаселенныйПунктАдреса(НаселенныйПункт, НаселенныйПунктДетально, ИменаУровнейАдреса);
		
	КонецЕсли;
	
	Если Не АдресВосстановлен Тогда
		
		Если МеждународныйФорматАдреса Тогда
			ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес();
		ИначеЕсли Не ЭтоРФАдрес() Тогда
			
			Если Не СведенияОСтране.УчастникЕАЭС Тогда
				
				ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес();
				ИменаУровнейАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(ТипАдреса, Ложь);
				НаселенныйПунктДетально[ИменаУровнейАдреса[0]] = НаселенныйПункт;
				ОбновитьСписокУровней(НаселенныйПунктДетально, ИменаУровнейАдреса[0], ЗначениеЗаполнено(НаселенныйПункт));
				ОбновитьПредставлениеАдреса();
				Возврат;
				
			КонецЕсли;
			
			ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.АдресЕАЭС();
		
		КонецЕсли;
		
		ИменаУровнейАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(НаселенныйПунктДетально.addressType, Ложь);
		
		ПорядокУровнейВАдресе = Новый Массив;
		
		Если ИменаУровнейАдреса.Количество() = 1 Тогда
			НаселенныйПунктДетально[ИменаУровнейАдреса[0]] = НаселенныйПункт;
			ОбновитьСписокУровней(НаселенныйПунктДетально, ИменаУровнейАдреса[0], ЗначениеЗаполнено(НаселенныйПункт));
		Иначе
			
			ЭлементыАдреса = СтрРазделить(НаселенныйПункт, ",", Истина);
			Для ИндексАдреса = 0 По ИменаУровнейАдреса.Количество() - 1 Цикл
				ИмяУровня = ИменаУровнейАдреса[ИндексАдреса];
				
				Если ЭлементыАдреса.Количество() > 0 Тогда
					ЗначениеПоля = СокрЛП(ЭлементыАдреса[0]);
					
					Если ЭтоРФАдрес() Тогда
						Позиция = СтрНайти(ЗначениеПоля, " ", НаправлениеПоиска.СНачала);
					Иначе
						Позиция = 0;
					КонецЕсли;
					
					Если Позиция > 0 Тогда
						НаселенныйПунктДетально[ИмяУровня] = СокрЛП(Сред(ЗначениеПоля, Позиция + 1));
						НаселенныйПунктДетально[ИмяУровня + "Type"] = СокрЛП(Лев(ЗначениеПоля, Позиция));
					Иначе
						НаселенныйПунктДетально[ИмяУровня] = ЗначениеПоля;
					КонецЕсли;
					ЭлементыАдреса.Удалить(0);
					ПорядокУровнейВАдресе.Добавить(ИмяУровня);
				Иначе
					НаселенныйПунктДетально[ИмяУровня] = "";
				КонецЕсли;
			КонецЦикла;
			
			Если РаботаСАдресамиКлиентСервер.ЭтоМуниципальныйАдрес(НаселенныйПунктДетально.addressType) Тогда
				НаселенныйПунктДетально.munLevels = ПорядокУровнейВАдресе;
				ИмяПоляДругогоТипаАдреса = "admLevels";
				ИменаУровнейДругогоТипаАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(
					РаботаСАдресамиКлиентСервер.АдминистративноТерриториальныйАдрес(), Ложь);
			Иначе
				НаселенныйПунктДетально.admLevels = ПорядокУровнейВАдресе;
				ИмяПоляДругогоТипаАдреса = "munLevels";
				ИменаУровнейДругогоТипаАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(
					РаботаСАдресамиКлиентСервер.МуниципальныйАдрес(), Ложь);
			КонецЕсли;
			
			НаселенныйПунктДетально[ИмяПоляДругогоТипаАдреса] = Новый Массив;
			Для каждого ИмяУровня Из ИменаУровнейДругогоТипаАдреса Цикл
				ОбновитьСписокУровней(НаселенныйПунктДетально, ИмяУровня, ЗначениеЗаполнено(НаселенныйПунктДетально[ИмяУровня]));
			КонецЦикла; 
		
			Если ЭлементыАдреса.Количество() > 0 Тогда
				НаселенныйПунктДетально[ИменаУровнейАдреса[ИменаУровнейАдреса.Количество() - 1]] = СокрЛП(СтрСоединить(ЭлементыАдреса, ","));
			КонецЕсли;
		КонецЕсли;
		
	КонецЕсли;
	
	ОбновитьПредставлениеАдреса();
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция ВосстановитьНаселенныйПунктАдреса(НаселенныйПункт, НаселенныйПунктДетально, ИменаУровнейАдреса)
	
	Результат = УправлениеКонтактнойИнформацией.КонтактнаяИнформацияПоПредставлению(НаселенныйПункт, Перечисления.ТипыКонтактнойИнформации.Адрес);
	
	Адрес = УправлениеКонтактнойИнформациейСлужебный.JSONВКонтактнуюИнформациюПоПолям(Результат, Перечисления.ТипыКонтактнойИнформации.Адрес);
	Если УправлениеКонтактнойИнформацией.АдресВведенВСвободнойФорме(Адрес) Тогда
		Возврат Ложь;
	КонецЕсли;
	
	Для каждого ИмяУровняАдреса Из ИменаУровнейАдреса Цикл
		НаселенныйПунктДетально[ИмяУровняАдреса] = Адрес[ИмяУровняАдреса];
		НаселенныйПунктДетально[ИмяУровняАдреса + "Type"] = Адрес[ИмяУровняАдреса + "Type"];
		ОбновитьСписокУровней(НаселенныйПунктДетально, ИмяУровняАдреса, ЗначениеЗаполнено(Адрес[ИмяУровняАдреса]));
	КонецЦикла;
	
	УстановитьИдентификаторыАдреса(НаселенныйПунктДетально);
	
	Возврат Истина;
	
КонецФункции

&НаКлиенте
Процедура ПоказатьПодсказкуПоТипАдреса()
	
	Если МеждународныйФорматАдреса Тогда
		Элементы.СтраницаТипАдреса.ТекущаяСтраница = Элементы.СтраницаДругойАдрес;
		Элементы.НужнаПомощь.Видимость = Ложь;
	ИначеЕсли РаботаСАдресамиКлиентСервер.ЭтоМуниципальныйАдрес(НаселенныйПунктДетально.AddressType) Тогда
		Элементы.СтраницаТипАдреса.ТекущаяСтраница = Элементы.СтраницаМуниципальныйАдрес;
		Элементы.НужнаПомощь.Видимость = Истина;
	ИначеЕсли РаботаСАдресамиКлиент.ЭтоАдминистративноТерриториальныйАдрес(НаселенныйПунктДетально.AddressType) Тогда
		Элементы.СтраницаТипАдреса.ТекущаяСтраница = Элементы.СтраницаАдминистративноТерриториальныйАдрес;
		Элементы.НужнаПомощь.Видимость = Истина;
	Иначе
		Элементы.СтраницаТипАдреса.ТекущаяСтраница = Элементы.СтраницаДругойАдрес;
		Элементы.НужнаПомощь.Видимость = Ложь;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаИзмененияАдреса(ОбновитьДополнительныеЗдания = Истина)
	
	НаселенныйПункт = ПредставлениеНаселенногоПунктаАдреса(НаселенныйПунктДетально);
	
	Улица = ?(ПустаяСтрока(НаселенныйПунктДетально.Street), "",
		УправлениеКонтактнойИнформациейКлиентСервер.СоединитьНаименованиеИТипАдресногоОбъекта(
			НаселенныйПунктДетально.Street, НаселенныйПунктДетально.StreetType));
		
	Если ПустаяСтрока(НаселенныйПунктДетально.country) И (ЗначениеЗаполнено(НаселенныйПункт) Или ЗначениеЗаполнено(Улица)) Тогда
		НаселенныйПунктДетально.country = ?(ЗначениеЗаполнено(Страна), Строка(Страна), РаботаСАдресамиКлиентСервер.ОсновнаяСтрана());
	КонецЕсли;
	
	ОбновитьПредставлениеАдреса();
	
	ФорматАдреса = НаселенныйПунктДетально.AddressType;
	Индекс       = НаселенныйПунктДетально.ZIPCode;
	ОКТМО        = НаселенныйПунктДетально.OKTMO;
	
	Если ЗначениеЗаполнено(НаселенныйПунктДетально.HouseType) Тогда
		ТипДома = НаселенныйПунктДетально.HouseType;
	КонецЕсли;
	
	Если ПустаяСтрока(НаселенныйПунктДетально.stead) Тогда
		Дом = НаселенныйПунктДетально.HouseNumber;
	Иначе
		Дом = НаселенныйПунктДетально.stead;
	КонецЕсли;
	
	Если НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
		Если ЗначениеЗаполнено(НаселенныйПунктДетально.buildings[0].Type) Тогда
			ТипСтроения = НаселенныйПунктДетально.buildings[0].Type;
		КонецЕсли;
		
		Строение = НаселенныйПунктДетально.buildings[0].Number;
	Иначе
		Строение = "";
	КонецЕсли;
	
	Если НаселенныйПунктДетально.Apartments.Количество() > 0 Тогда
		Если ЗначениеЗаполнено(НаселенныйПунктДетально.Apartments[0].Type) Тогда
			ТипПомещения = НаселенныйПунктДетально.Apartments[0].Type;
		КонецЕсли;
		
		Помещение = НаселенныйПунктДетально.Apartments[0].Number;
		
	Иначе
		Помещение = "";
	КонецЕсли;
	
	УстановитьФлагиВМенюПоТипуАдреса();
	Если ОбновитьДополнительныеЗдания Тогда
		ПодключитьОбработчикОжидания("ОбновитьДополнительныеЗдания", 0.1, Истина);
	КонецЕсли;
	
	Если ЗначениеЗаполнено(Комментарий) Тогда
		Элементы.ОсновныеСтраницы.ОтображениеСтраниц = ОтображениеСтраницФормы.ЗакладкиСверху;
		Элементы.СтраницаКомментарий.Картинка = ОбщегоНазначенияКлиентСервер.КартинкаКомментария(Комментарий);
	Иначе
		Элементы.ОсновныеСтраницы.ТекущаяСтраница = Элементы.СтраницаАдрес;
		Элементы.ОсновныеСтраницы.ОтображениеСтраниц = ОтображениеСтраницФормы.Нет;
	КонецЕсли;
	
	Модифицированность = Истина;
	
КонецПроцедуры

&НаКлиенте
Функция ПредставлениеНаселенногоПунктаАдреса(Адрес)
	
	СписокЗаполненныхУровней = Новый Массив;
	
	ПорядокУровнейВАдресе = РаботаСАдресамиКлиентСервер.ИменаУровнейАдресаПоАдресу(Адрес, Ложь);
	
	Для каждого ИмяУровня Из ПорядокУровнейВАдресе Цикл
		
		Если ЗначениеЗаполнено(Адрес[ИмяУровня]) Тогда
			
			Если СтрСравнить(ИмяУровня, "street") = 0 Тогда
				Продолжить;
			КонецЕсли;
			
			СписокЗаполненныхУровней.Добавить(РаботаСАдресамиКлиентСервер.ПредставлениеУровняАдреса(Адрес, ИмяУровня));
			
		КонецЕсли;
				
	КонецЦикла;
	
	Возврат СтрСоединить(СписокЗаполненныхУровней, ", ");
	
КонецФункции

&НаКлиенте
Процедура УстановитьФлагиВМенюПоТипуАдреса()
	
	Если УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType) Тогда
		Элементы.АдресВСвободнойФорме.Пометка                  = Истина;
		Элементы.МуниципальноеДеление.Пометка                  = Ложь;
		Элементы.АдминистративноТерриториальноеДеление.Пометка = Ложь;
	ИначеЕсли РаботаСАдресамиКлиентСервер.ЭтоМуниципальныйАдрес(НаселенныйПунктДетально.AddressType) Тогда
		Элементы.АдресВСвободнойФорме.Пометка                  = Ложь;
		Элементы.МуниципальноеДеление.Пометка                  = Истина;
		Элементы.АдминистративноТерриториальноеДеление.Пометка = Ложь;
		Элементы.ПроверитьЗаполнениеАдреса.Доступность         = Истина;
	ИначеЕсли РаботаСАдресамиКлиент.ЭтоАдминистративноТерриториальныйАдрес(НаселенныйПунктДетально.AddressType) Тогда
		Элементы.АдресВСвободнойФорме.Пометка                  = Ложь;
		Элементы.МуниципальноеДеление.Пометка                  = Ложь;
		Элементы.АдминистративноТерриториальноеДеление.Пометка = Истина;
		Элементы.ПроверитьЗаполнениеАдреса.Доступность         = Истина;
	Иначе
		Элементы.МуниципальноеДеление.Пометка                  = Ложь;
		Элементы.АдминистративноТерриториальноеДеление.Пометка = Ложь;
		Элементы.АдресВСвободнойФорме.Пометка                  = Ложь;
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПереключитьНаСтруктурированныйВвод(ТипАдреса = Неопределено)
	
	Если УправлениеКонтактнойИнформациейКлиентСервер.ЭтоАдресВСвободнойФорме(НаселенныйПунктДетально.AddressType) Тогда
		РазрешитьВводАдресаВСвободнойФорме = Ложь;
		ТекстВопроса = НСтр("ru = 'Изменения, введенные вручную, будут потеряны.
		|Исходный адрес будет перемещен в комментарий.
		|Продолжить?'");
		
		Если МеждународныйФорматАдреса Тогда
			ТипАдреса = УправлениеКонтактнойИнформациейКлиентСервер.ИностранныйАдрес();
		КонецЕсли;
		
		ДополнительныеПараметры = Новый Структура("ТипАдреса", ТипАдреса);
		Оповещение = Новый ОписаниеОповещения("ПереключитьНаСтруктурированныйВводЗавершение", ЭтотОбъект, ДополнительныеПараметры );
		
		ПоказатьВопрос(Оповещение, ТекстВопроса, РежимДиалогаВопрос.ДаНет,,, НСтр("ru = 'Подтверждение'"));
	Иначе
		ОтобразитьВыбранныйТипАдреса(ТипАдреса);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиенте
Процедура ПереключитьНаСтруктурированныйВводЗавершение(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат <> КодВозвратаДиалога.Да Тогда
		Возврат;
	КонецЕсли;
	
	Комментарий = ?(НЕ ПустаяСтрока(Комментарий), Комментарий + Символы.ПС, "")
			+ НСтр("ru = 'Исходный адрес:'") + " " + ПредставлениеАдреса;
	НаселенныйПунктДетально.comment = Комментарий;
	
	ПодключитьОбработчикОжидания("УстановитьПиктограммуКомментария", 0.1, Истина);
	
	ОтобразитьВыбранныйТипАдреса(ДополнительныеПараметры.ТипАдреса);
	
КонецПроцедуры

&НаКлиенте
Процедура ОчиститьИдентификаторыАдреса()
	Для каждого ЭлементАдреса Из НаселенныйПунктДетально Цикл
		Если СтрЗаканчиваетсяНа(ЭлементАдреса.Ключ, "Id") Тогда
			НаселенныйПунктДетально[ЭлементАдреса.Ключ] = "";
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

&НаСервереБезКонтекста
Процедура УстановитьИдентификаторыАдреса(Адрес)
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		МодульАдресныйКлассификаторСлужебный = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификаторСлужебный");
		МодульАдресныйКлассификаторСлужебный.УстановитьИдентификаторыАдреса(Адрес);
	КонецЕсли;
	
КонецПроцедуры

&НаКлиентеНаСервереБезКонтекста
Функция ИдентификаторАдреса(Адрес, ВключатьУлицу, ВключатьУровеньДома = Ложь)
	
	ИдентификаторАдреса = Неопределено;
	
	Уровни = РаботаСАдресамиКлиентСервер.ИменаУровнейАдресаПоАдресу(Адрес, ВключатьУлицу, ВключатьУровеньДома);
	
	Для каждого Уровень Из Уровни Цикл
		
		Если Адрес.Свойство(Уровень + "Id")
			И ЗначениеЗаполнено(Адрес[Уровень+ "Id"]) Тогда
				ИдентификаторАдреса = Адрес[Уровень + "Id"];
		КонецЕсли;
		
	КонецЦикла;
	
	Возврат ИдентификаторАдреса;
	
КонецФункции

&НаСервереБезКонтекста
Функция НайтиИндексУДома(АдресныйОбъект, Дом)
	
	ПолныйСписокДомов = Обработки.РасширенныйВводКонтактнойИнформации.СписокДомов(АдресныйОбъект, Дом, 1);
	Если ПолныйСписокДомов.Количество() > 0 Тогда
		Возврат ПолныйСписокДомов[0].Значение.Индекс;
	КонецЕсли;
	
	Возврат "";
	
КонецФункции

&НаКлиенте
Процедура ОткрытьФормуЗагрузкиКлассификатора()
	
	ДополнительныеПараметры = Новый Структура();
	
	Если ТипЗнч(НаселенныйПунктДетально) = Тип("Структура") И НаселенныйПунктДетально.Свойство("Area") Тогда
		СведенияОРегионе = СведенияОРегионе(НаселенныйПунктДетально.area, НаселенныйПунктДетально.areaType);
		ДополнительныеПараметры.Вставить("КодРегионаДляЗагрузки", СведенияОРегионе.КодСубъектаРФ);
	КонецЕсли;
	
	ЗагрузитьАдресныйКлассификатор(ДополнительныеПараметры);

КонецПроцедуры

&НаСервереБезКонтекста
Процедура УстановитьМуниципальныеЧастиАдреса(НаселенныйПунктДетально, ВыбранноеЗначение)
	
	Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		
		ТипЧисло = Новый ОписаниеТипов("Число");
		ОКТМО = ТипЧисло.ПривестиЗначение(ВыбранноеЗначение.ОКТМО);
		
		ЗагруженныеДанные = ВыбранноеЗначение.ЗагруженныеДанные;
		
		Если ЗагруженныеДанные Тогда
			ИдентификаторАдреса = ИдентификаторАдреса(НаселенныйПунктДетально, Истина);
		Иначе
			Если ЗначениеЗаполнено(ВыбранноеЗначение.ИдентификаторДома) Тогда
				ИдентификаторАдреса = ВыбранноеЗначение.ИдентификаторДома;
			Иначе
				ИдентификаторАдреса = ИдентификаторАдреса(НаселенныйПунктДетально, Истина, Не ЗагруженныеДанные);
			КонецЕсли;
		КонецЕсли;
		
		МодульАдресныйКлассификаторСлужебный = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификаторСлужебный");
		МодульАдресныйКлассификаторСлужебный.УстановитьМуниципальныеСведения(НаселенныйПунктДетально, ОКТМО, 
			ИдентификаторАдреса, ЗагруженныеДанные);
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура СформироватьТекстНужнаПомощь()
	
	Если Не ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
		Возврат;
	КонецЕсли;
	
	Если ВидКонтактнойИнформации.ПроверятьКорректность И Не ВидКонтактнойИнформации.МожноИзменятьСпособРедактирования Тогда
		Возврат;
	КонецЕсли;
	
	ДополнительныйТекст = Символы.ПС + Символы.ПС + НСтр("ru = 'Также адрес можно ввести в свободной форме (см. Еще - Адрес в свободной форме).'");
	
	Если ВидКонтактнойИнформации.МожноИзменятьСпособРедактирования И ВидКонтактнойИнформации.ПроверятьКорректность Тогда
		ДополнительныйТекст = ДополнительныйТекст + " "+ СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
			НСтр("ru = 'Для этого предварительно снять флажок ""Запрещать ввод некорректных адресов"" в виде контактной информации ""%1"".'"),
			ОписаниеВидаКонтактнойИнформации(ЭтотОбъект).Ссылка);
		
	КонецЕсли;
	
	Элементы.ДекорацияНужнаПомощь.Заголовок = Новый ФорматированнаяСтрока(Элементы.ДекорацияНужнаПомощь.Заголовок, ДополнительныйТекст);
	
КонецПроцедуры

&НаСервереБезКонтекста
Функция СведенияОбАдресе(НаселенныйПунктДетально) 
	
	АдресВJSON = УправлениеКонтактнойИнформациейСлужебный.СтруктураВСтрокуJSON(НаселенныйПунктДетально);
	ДополнительныеПараметры = Новый Структура;
	ДополнительныеПараметры.Вставить("КодыАдреса", Истина);
	Возврат РаботаСАдресами.СведенияОбАдресе(АдресВJSON, ДополнительныеПараметры);
	
КонецФункции

// Возвращаемое значение:
//   см. УправлениеКонтактнойИнформациейСлужебный.СтруктураВидаКонтактнойИнформации
//
&НаКлиентеНаСервереБезКонтекста
Функция ОписаниеВидаКонтактнойИнформации(Форма)
	Возврат Форма.ВидКонтактнойИнформации;
КонецФункции

// Параметры:
//  Страна - Структура 
// Возвращаемое значение:
//   см. УправлениеКонтактнойИнформацией.ДанныеСтраныМира
//
&НаКлиентеНаСервереБезКонтекста
Функция ДанныеСтраныМира(Страна) 
	Возврат Страна;
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция НаименованиеСтраны(Страна, МеждународныйФорматАдреса)
	
	СведенияОСтране = СведенияОСтране(Страна);
	
	НаименованиеСтраны = СведенияОСтране.Наименование;
	Если МеждународныйФорматАдреса Тогда
		Если ЗначениеЗаполнено(СведенияОСтране.МеждународноеНаименование) Тогда
			НаименованиеСтраны = СведенияОСтране.МеждународноеНаименование;
		КонецЕсли;
	КонецЕсли;
	Возврат НаименованиеСтраны;
	
КонецФункции

// Конструкторы 

&НаКлиенте
Функция ПараметрыОткрытияФормыНаселенногоПункта()
	
	ПараметрыФормы = Новый Структура;
	ПараметрыФормы.Вставить("НаселенныйПунктДетально", НаселенныйПунктДетально);
	ПараметрыФормы.Вставить("ОтображатьКнопкиВыбора",  ИспользуетсяАдресныйКлассификатор);
	ПараметрыФормы.Вставить("ТипАдреса",               ТипАдреса);
	
	Возврат ПараметрыФормы;
	
КонецФункции

&НаКлиенте
Функция ПараметрыОткрытияФормаВыбораПоИндексу()
	
	ПараметрыФормы = Новый Структура;
	
	ПараметрыФормы.Вставить("Индекс",                        "");
	ПараметрыФормы.Вставить("ВыборАдресаПоПочтовомуИндексу", Истина);
	ПараметрыФормы.Вставить("ТипАдреса",                     ТипАдреса);
	
	Возврат ПараметрыФормы;
	
КонецФункции

&НаКлиентеНаСервереБезКонтекста
Функция НачалоУчета()
	
	Возврат НСтр("ru = 'начало учета'");
	
КонецФункции

&НаКлиенте
Процедура ПослеАвторизоватьНаСайтеПоддержкиПользователей(Результат, ДополнительныеПараметры) Экспорт
	
	Если Результат = Неопределено Тогда
		ОткрытьФормуЗагрузкиКлассификатора();
		Возврат;
	КонецЕсли;
	
	ОбновитьПовторноИспользуемыеЗначения();
	ВебКлассификаторДоступен = Истина;
	СообщениеОНеобходимостиЗагрузкиКлассификатора();
	
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораУлицы(Результат, ДополнительныеПараметры) Экспорт
	
	Если ТипЗнч(Результат) = Тип("Структура") Тогда
		Если Не Результат.Отказ Тогда
			НаселенныйПунктДетально = ОпределитьАдресПоИдентификатору(Результат);
			ОбработкаИзмененияАдреса();
		КонецЕсли;
	Иначе
		ПоказатьПредупреждение(, НСтр("ru = 'Выбор из списка недоступен, т.к в адресном классификаторе отсутствует информация об улицах для введенного населенного пункта.'"));
	КонецЕсли;
	
КонецПроцедуры

// Параметры:
//  Результат - см. РаботаСАдресамиКлиентСервер.ВозвращаемыеДанныеОбАдресе
//  ДополнительныеПараметры - Неопределено
//
&НаКлиенте
Процедура ПослеВводаСведенийНаселенногоПункта(Результат, ДополнительныеПараметры) Экспорт
	
	Если ТипЗнч(Результат) = Тип("Структура") Тогда
		
		НаселенныйПунктДетально = Результат.НаселенныйПунктДетально;
		ОбработкаИзмененияАдреса();
		
	КонецЕсли;
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнениеПолейАдресаДляРанееВведенныхАдресов()
	
	Если ЗначениеЗаполнено(НаселенныйПунктДетально.value) Тогда
		
		Если ПустаяСтрока(НаселенныйПунктДетально.areaValue) Тогда
			Если ОбщегоНазначения.ПодсистемаСуществует("СтандартныеПодсистемы.АдресныйКлассификатор") Тогда
			
				МодульАдресныйКлассификатор = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификатор");
			
				Если ПустаяСтрока(НаселенныйПунктДетально.areaCode) Тогда
					НаселенныйПунктДетально.areaCode = МодульАдресныйКлассификатор.КодРегионаПоНаименованию(
						УправлениеКонтактнойИнформациейКлиентСервер.СоединитьНаименованиеИТипАдресногоОбъекта(НаселенныйПунктДетально.area, 
						НаселенныйПунктДетально.areaType, Истина))
				КонецЕсли;
				
				МодульАдресныйКлассификаторСлужебный = ОбщегоНазначения.ОбщийМодуль("АдресныйКлассификаторСлужебный");
				НаселенныйПунктДетально.areaValue = МодульАдресныйКлассификаторСлужебный.ПолноеНаименованиеРегионаПоКоду(НаселенныйПунктДетально.areaCode);
				
			КонецЕсли;
		КонецЕсли;
		
		Если НаселенныйПунктДетально.munLevels.Количество() = 0 Тогда
			УровниАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(РаботаСАдресамиКлиентСервер.МуниципальныйАдрес(), Истина);
			Для Каждого УровеньАдреса Из УровниАдреса Цикл
				Если ЗначениеЗаполнено(НаселенныйПунктДетально[УровеньАдреса]) Тогда
					НаселенныйПунктДетально.munLevels.Добавить(УровеньАдреса);
				КонецЕсли;
			КонецЦикла;
			
			Если ЗначениеЗаполнено(НаселенныйПунктДетально.houseNumber) Или НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
				НаселенныйПунктДетально.munLevels.Добавить("house");
			КонецЕсли;
			
		КонецЕсли;
		
		Если НаселенныйПунктДетально.admLevels.Количество() = 0 Тогда
			УровниАдреса = РаботаСАдресамиКлиентСервер.ИменаУровнейАдреса(РаботаСАдресамиКлиентСервер.АдминистративноТерриториальныйАдрес(), Истина);
			Для Каждого УровеньАдреса Из УровниАдреса Цикл
				Если ЗначениеЗаполнено(НаселенныйПунктДетально[УровеньАдреса]) Тогда
					НаселенныйПунктДетально.admLevels.Добавить(УровеньАдреса);
				КонецЕсли;
			КонецЦикла;
			
			Если ЗначениеЗаполнено(НаселенныйПунктДетально.houseNumber) Или НаселенныйПунктДетально.buildings.Количество() > 0 Тогда
				НаселенныйПунктДетально.admLevels.Добавить("house");
			КонецЕсли;
			
		КонецЕсли;
		
	КонецЕсли;

КонецПроцедуры

#КонецОбласти